Ну, вы столкнулись с Диким Западом с плавающей точкой!Не доверяйте никому, не ожидайте многого, держите руку на ружье.
Дело в том, что представление с плавающей запятой - это раскол.Заданное количество байтов расходуется на хранение двух частей, значения мантиссы и десятой степени (это, конечно, упрощенное описание, однако этого здесь хватит).Если у вас есть значение, которое слишком велико, чтобы поместиться в мантиссе, что должен делать компьютер?Он должен переносить остаток в другую часть байтов (как это делают библиотеки Big Math) или просто округлять до ближайшего возможного значения.Позвольте мне показать:
d2 = 0.5700788999; // shows 0.5700788999000001
d2 = 1300010000000000000000.5700788999; // shows 1300009999999999934464.0000000000000000000
Эй, где моя дробная часть во втором случае?Это прошло!Вызовите полицию!Ой, подождите, это просто не вписывается ... Вот почему diff дает ноль: мантиссы настолько огромны, что хвостовая часть (там, где есть реальная разница) не может быть сохранена.И как только остальные цифры совпадают, мы получаем нулевую разницу.
После тщательного сравнения вы можете заметить еще одну вещь: напечатанное значение близко к назначенному, однако оно немного отличается.Это потому, что мантисса - это просто сумма степеней 2. Таким образом, чтобы представить значение, компьютер должен округлить присвоенное значение до ближайшего двоично-совместимого значения.Иногда это другой вид боли, и вам не следует сравнивать числа с плавающей запятой с помощью оператора равенства, просто оцените разницу и сравните ее с ожидаемой дельтой предполагаемой точности.