Cela se résume au fait que 0.62
n'est pas exactement représentable dans un type de données à virgule flottante binaire. Le closest representable double value to 0.62
est:
0.61999 99999 99999 99555 91079 01499 37383 83054 73327 63671 875
Lorsque vous multipliez cette valeur par 100, la valeur résultante est légèrement inférieure à 62. L'étape suivante dépend de la façon dont est traitée la valeur intermédiaire d*100
. Dans votre programme, sous le compilateur Windows 32 bits avec les paramètres par défaut, la valeur intermédiaire est conservée dans un registre étendu de 80 bits. Et le plus proche 80 bits valeur de précision étendue est:
61.99999 99999 99999 55591 07901 49937 38383 05473 32763 67187 5
Puisque la valeur est inférieure à 62, 61 Trunc
rendements depuis Trunc
tours vers zéro.
Si vous avez enregistré d*100
dans une valeur double, le résultat est différent.
d := 0.62;
d := d*100;
i := Trunc(d);
Writeln(i);
Ce programme génère 62 plutôt que 61. En effet, bien que d*100
à étendre 80 précision de bits est inférieur à 62, le closest double precision value to that 80 bit value est en fait 62.
De même, si vous compilez votre programme original avec le Compilateur 64 bits, puis l'arithmétique est effectuée dans l'unité SSE qui n'a pas de registres 80 bits. Ou alors, il n'y a pas de valeur intermédiaire 80 bits et votre programme sort 62.
Ou, en remontant au compilateur 32 bits, vous pouvez organiser que les valeurs intermédiaires sont stockées à 64 bits de précision sur la FPU et également atteindre une sortie de 62. Appelez Set8087CW($1232)
pour y parvenir.
Comme vous pouvez le voir, l'arithmétique binaire en virgule flottante peut parfois surprendre.
Si vous utilisez Round
plutôt que Trunc
la valeur retournée sera l'entier le plus proche, au lieu d'arrondir vers zéro comme Trunc
fait.
Mais peut-être une meilleure solution serait d'utiliser un type de données décimal plutôt qu'un type de données binaire. Si vous faites cela, vous pouvez représenter exactement 0,62 et ainsi éviter tous ces problèmes. Le type de données décimal à valeur décimale intégré de Delphi est Currency
.
Copie possible de [Est-ce que le calcul à virgule flottante est rompu?] (Http://stackoverflow.com/questions/588004/is-floating-point-math-broken) – Mark