Comme Jon Skeet l'écrit ci-dessus, la raison pour laquelle vous obtenez 0.179999999999999993338661852249060757458209991455078125
au lieu de 0.18
est parce que 0.06 * 3
est calculé comme un IEEE 754 double
et ensuite ceci double
est convertie en une valeur BigDecimal
.
Même si 0.06
semble assez simple dans le code source, le nombre 0,06 n'est pas exactement représentable comme un IEEE 754. double
Et alors ? 0.06
représente en fait un approximation de 0,06 égal à 0,05999999999999977795539507496869191527363818359375. Le nombre 0,06 en notation décimale n'est pas exactement représentable car le nombre est égal à 0b0.0 00011110101110000101 en notation binaire (où en gras représente une séquence de chiffres répétitifs). L'ordinateur doit tronquer cette séquence infinie de chiffres binaires, ce qui conduit à l'approximation 0,0599999....
Comme je l'ai détaillé dans ma réponse à la question concernant IEEE 754, 64 bits double ? vous pouvez utiliser ARIBAS ' decode_float()
pour déterminer la mantisse et l'exposant d'un nombre à virgule flottante :
\==> set\_floatprec(double\_float).
-: 64
==> set\_printbase(2).
-: 0y10
==> decode\_float(0.06).
-: (0y11110101\_11000010\_10001111\_01011100\_00101000\_11110101\_11000010\_10001111,
-0y1000100)
==> set\_printbase(10).
-: 10
==> -0y1000100.
-: -68
==> set\_floatprec(128).
-: 128
==> 1/2\*\*4 + 1/2\*\*5 + 1/2\*\*6 + 1/2\*\*7 + 1/2\*\*9 + 1/2\*\*11 + 1/2\*\*12 + 1/2\*\*13 + 1/2\*\*18 + 1/2\*\*20.
-: 0.11999\_98855\_59082\_03125\_00000\_00000\_00000\_00
( **
est une exponentiation en ARIBAS).
Et nous avons 0,06 = Σ i = 0..∞ 0.11999988555908203125 / 2 <sup>1 + 20 × i</sup>
Vous pouvez évaluer cette série dans un système de calcul formel tel que Maxima :
(%i1) sum ( 0.11999988555908203125 / 2 ^ (1 + 20 \* i), i, 0, inf ), simpsum;
(%o1) 0.06
http://maxima-online.org/?inc=r760264757