Инвертируемость деления с плавающей запятой IEEE 754

Что такое инвертируемость деления с плавающей запятой IEEE 754? Я имею в виду, гарантируется ли стандартом, что если double y = 1.0 / x, то x == 1.0 / y, т.е. x можно восстановить по частям бит?

Случаями, когда y является infinity или NaN, являются очевидными исключениями.

Ответы

Ответ 1

Да, существуют значения двойной точности (*) IEEE 754 x, которые являются такими x != 1.0 / (1.0 / x).

Легко построить пример нормального значения с этим свойством вручную: тот, который записал 0x1.fffffffffffffp0 в шестнадцатеричную нотацию C99 для значений с плавающей запятой таково, что 1.0 / (1.0 / 0x1.fffffffffffffp0) == 0x1.ffffffffffffep0. Естественно ожидать, что 0x1.fffffffffffffp0 будет контр-примером, потому что 1.0 / 0x1.fffffffffffffp0 падает в начале бинада, где числа с плавающей запятой менее плотные, поэтому более большая относительная ошибка должна была произойти в самом внутреннем делении. Точнее, 1.0 / 0x1.fffffffffffffp0 падает чуть выше середины между 0.5 и преемником двойной точности, так что 1.0 / 0x1.fffffffffffffp0 округляется до преемника 0.5 с большой относительной ошибкой.

В десятичном формате %.16e 0x1.fffffffffffffp0 есть 1.9999999999999998e+00 и 0x1.ffffffffffffep0 есть 1.9999999999999996e+00.

(*) нет никакой причины, чтобы обратная функция имела свойство в вопросе для любого из формата IEEE 754

Ответ 2

Очевидно, нет. 1/10 не имеет представления. Вместо этого вы получаете приближение. Инвертирование, которое не даст вам 10.

Изменить: их много. Любой обратный, который требует более 53 бит, будет одним из них.

Простой тест. В C вы можете протестировать 1.0/(1.0/10.0) против 10.0, и вы обнаружите, что они не равны.