var sum = 0; for(var i = 0; i < 10; i++) { sum += 0.1; } console.log(sum);
Le programme ci-dessus produira-t-il 1 ?
Dans l'article 25 questions d'entretien JavaScript que vous devez connaître , la 8ème question explique brièvement pourquoi js ne peut pas gérer correctement les opérations décimales. Aujourd'hui, je vais revenir sur un vieux sujet et analyser cette question de manière plus approfondie.
Mais tout d'abord, il convient de noter que l'incapacité à gérer correctement les opérations décimales n'est pas une erreur de conception dans le langage JavaScript lui-même. D'autres langages de programmation de haut niveau, tels que C, Java, etc., en sont également incapables. pour gérer correctement les opérations décimales :
#include <stdio.h> void main(){ float sum; int i; sum = 0; for(i = 0; i < 100; i++) { sum += 0.1; } printf('%f\n', sum); //10.000002 }
Représentation des nombres à l'intérieur de l'ordinateur
Nous savons tous que les programmes écrits dans des langages de programmation de haut niveau doivent être convertis en langage machine pouvant être reconnu par le CPU (Central Processing Unit) via l'interprétation, la compilation et d'autres opérations avant de pouvoir être exécutés. , pour le CPU, il ne reconnaît pas les systèmes de nombres décimaux et décimaux octal et hexadécimal, etc., ces nombres de base que nous déclarons dans le programme seront convertis en nombres binaires pour le calcul.
Pourquoi ne pas le convertir en nombres ternaires pour le calcul ?
L'intérieur d'un ordinateur est composé de nombreux composants électroniques tels que des IC (Integrated Circuit : Integrated Circuit). Il ressemble à ceci :
Les circuits intégrés se présentent sous de nombreuses formes, avec de nombreuses broches disposées côte à côte des deux côtés ou à l'intérieur (un seul côté est montré sur l'image). Toutes les broches du circuit intégré n'ont que deux états de tension continue 0 V ou 5 V, c'est-à-dire qu'une broche du circuit intégré ne peut représenter que deux états. Cette caractéristique d'IC détermine que les données contenues dans l'ordinateur ne peuvent être traitées qu'avec des nombres binaires.
Puisque 1 bit (une broche) ne peut représenter que deux états, la méthode de calcul binaire devient 0, 1, 10, 11, 100... Cette forme :
Ainsi, dans les opérations sur les nombres, tous les opérandes seront convertis en nombres binaires pour participer à l'opération, comme 39, sera converti en binaire 00100111
Représentation binaire des décimales
Comme mentionné ci-dessus, les données du programme seront converties en nombres binaires Lorsque des décimales sont impliquées dans des opérations, elles seront également converties en nombres binaires. Par exemple, le nombre décimal 11,1875 sera converti en 1101,0010.
La plage numérique exprimée par 4 chiffres après la virgule dans les nombres binaires est de 0,0000 ~ 0,1111. Par conséquent, cela ne peut représenter que la combinaison (addition) des quatre nombres décimaux 0,5, 0,25, 0,125, 0,0625 et les poids en bits après. le point décimal :
Comme le montre le tableau ci-dessus, le chiffre suivant du nombre décimal 0 est 0,0625. Par conséquent, les décimales entre 0 et 0,0625 ne peuvent pas être représentées par des nombres binaires avec 4 chiffres après la virgule décimale ; le point décimal, le nombre de chiffres décimaux correspondants augmentera également, mais quel que soit le nombre de chiffres ajoutés, le résultat de 0,1 ne peut pas être obtenu. En fait, 0,1 converti en binaire vaut 0,00110011001100110011... Notez que 0011 est répété à l'infini :
console.log(0.2+0.1); //操作数的二进制表示 0.1 => 0.0001 1001 1001 1001…(无限循环) 0.2 => 0.0011 0011 0011 0011…(无限循环)
Le type Number de js n'est pas divisé en entier, simple précision, double précision, etc. comme C/Java, mais est uniformément exprimé comme un type à virgule flottante double précision. Selon la réglementation IEEE, les nombres à virgule flottante simple précision utilisent 32 bits pour représenter toutes les décimales, tandis que les nombres à virgule flottante double précision utilisent 64 bits pour représenter toutes les décimales. Les nombres à virgule flottante sont composés d'un signe, d'une mantisse, d'un exposant et d'une base. , donc tous les chiffres ne sont pas utilisés. Pour représenter des décimales, les symboles, les exposants, etc. doivent également occuper des chiffres, et la base n'occupe pas de chiffres :
La partie décimale d'un nombre à virgule flottante double précision prend en charge jusqu'à 52 chiffres, donc après avoir ajouté les deux, vous obtenez une chaîne de 0,0100110011001100110011001100110011001100... un nombre binaire tronqué en raison de la limitation de la place décimale de le nombre à virgule flottante. À ce moment, convertissez-le en décimal, cela devient 0,30000000000000004.
Résumé
js ne peut pas gérer correctement les opérations décimales, y compris d'autres langages de programmation de haut niveau. Ce n'est pas une erreur de conception du langage lui-même, mais l'ordinateur lui-même ne peut pas gérer correctement les opérations décimales. Les opérations sur les décimales ne produisent souvent pas des résultats inattendus. les fractions décimales peuvent être représentées en binaire.
Ce qui précède représente l’intégralité du contenu de cet article, j’espère qu’il sera utile à l’étude de chacun.