Гарантируется ли, что a == b истинно?
Да.Это потому, что вы выполняете одно и то же преобразование дважды и, учитывая его детерминированное поведение, вы получите одинаковые значения независимо от проблем округления.
Мы можем обобщить ваш вопрос, однако:
Можем ли мы выполнить арифметические операции над 32-разрядными целочисленными значениями, закодированными в типе double
без потери точности?
Ответ на такой вопрос также положительный.
Короткийоправдание состоит в том, что операции над битами мантиссы (см. http://en.wikipedia.org/wiki/Significand) точны, если это возможно, а в случае 32-разрядных целочисленных значений это возможно.
Более длинная история приходит сюда. Пока вашцелочисленное значение помещается в 52 бита дробной части, называемой мантиссой (см. http://en.wikipedia.org/wiki/Double_precision), все вычисления целых значений с использованием double будут вести себя вполне нормально.
Это потому, что ваше число (скажем, 173, что составляет 0000010101101b
двоичный) будет представлен как 1.010110100000b*2^7
, что является точным.
Все операции с мантиссой выполняются прямо, если онивписывается в мантиссу.Округление по целым числам происходит, когда результат конкретной операции не укладывается в мантиссу - например.вы бы умножили 40 бит мантиссы на 40 бит мантиссы.Округление операций с плавающей запятой дополнительно происходит, когда показатели сильно отличаются.В этом случае даже простая операция сложения может потерять точность из-за смещения матиссы.
Возвращение к целым числам, закодированным в операции двойного четного деления, является точным, если в результате получается целочисленное значение.Так что 4.0/2.0 == 8.0/4.0
также гарантированно будет истинным.
Проблема начинается, когда ваш номер не является целым числом.Но даже в этом случае гарантируется, что числа будут точно представлены, если они имеют форму x/2^y
и x
в 52 бита (например, 3/4
5/8
345/1024
).Операции над такими числами также точны, поскольку y
может быть одинаковым для обоих операндов, поэтому даже:
123456789/1024/1024/1024/1024 ==
(23456789/1024/1024/1024/1024 +
100000000/1024/1024/1024/1024)
гарантированно будет истинным.
Интересный факт заключается в том, что вы можете выполнять операциюна 54-битных целых чисел со знаком безопасно.Это потому, что у вас есть дополнительный бит в начале, значение которого закодировано экспонентой, и один дополнительный бит для знака.Теперь -2 ^ 53, что будет MIN_INT в случае 54-битного целого числа со знаком, не соответствует мантиссе, но экспонента выполнит эту работу с мантиссой, полной нулей.