Это сводится к тому, что 0.62
не является точно представимым в двоичном виде с плавающей точкой. closest representable double value to 0.62
является:
0.61999 99999 99999 99555 91079 01499 37383 83054 73327 63671 875
Если умножить это значение на 100, полученное значение немного меньше, чем 62. Что произойдет дальше, зависит от того, как промежуточное значение d*100
лечится. В вашей программе под 32-битным компилятором Windows с настройками по умолчанию промежуточное значение сохраняется в 80-битном расширенном регистре. А ближе 80 бит расширенной точности значение:
61.99999 99999 99999 55591 07901 49937 38383 05473 32763 67187 5
Поскольку значение меньше 62, Trunc
возвращается 61 С Trunc
раундов к нулю.
Если вы сохранили d*100
в двойном значении, вы увидите другой результат.
d := 0.62;
d := d*100;
i := Trunc(d);
Writeln(i);
Эта программа выводит 62, а не 61. Это потому, что хотя d*100
расширенного 80 битной точности меньше, чем 62, то closest double precision value to that 80 bit value фактически 62.
Точно так же, если вы скомпилировать оригинальную программу с 64-битный компилятор, то арифметика выполняется в блоке SSE, который не имеет 80-битных регистров. И поэтому нет промежуточного значения 80 бит и выходов вашей программы 62.
Или, вернувшись к 32-битовому компилятору, вы можете организовать промежуточное значение, которое хранится до 64-битной точности на FPU, а также получить выход 62. Для этого необходимо позвонить Set8087CW($1232)
.
Как вы можете видеть, двоичная арифметика с плавающей запятой иногда может быть удивительной.
Если вы используете Round
вместо Trunc
то возвращаемое значение будет ближайшее целое число, а не округление к нулю, как Trunc
делает.
Но, возможно, лучшим решением было бы использовать десятичный тип данных, а не двоичный тип данных. Если вы это сделаете, вы можете точно представить 0.62 и тем самым избежать всех таких проблем. Встроенный десятичный реальный тип данных Delphi - Currency
.
Возможный дубликат [Является ли математика с плавающей запятой?] (Http://stackoverflow.com/questions/588004/is-floating-point-math-broken) – Mark