Учитывая 3 числа с плавающей запятой IEEE-754 a, b, c, которые не являются +/-INF и не NaN, и a ‹ b, можно ли предположить, что a - c ‹ b - c? Или вы можете привести пример, когда это неправильно?
Точность сравнения с плавающей запятой
Ответы (1)
Предположим, что a равно приблизительно 0,00000000000000001, b приблизительно равно 0,000000000000000002, а c равно 1. Тогда a c и b c будут равны 1.
(Это предполагает значения с двойной точностью, также известные как 64-битные значения. Для значений с более высокой точностью вам нужно будет добавить еще несколько нулей.)
Отредактировано для добавления объяснения:
Если мы проигнорируем денормализованные значения, нечисловые значения, бесконечности и т. д. и просто сосредоточимся на значение двойной точности с плавающей запятой IEEE 754, чтобы иметь что-то конкретное, на что можно было бы посмотреть, то с точки зрения двоичного представления значение с плавающей запятой состоит из знакового бита s (0 для положительного, 1 для отрицательного), одиннадцатибитный показатель степени e (со смещением 1023, так что e=0 означает 21023< /sup> и e=1023 означает 20, т. е. 1), и 52-битный мантиссанд с фиксированной точкой m (представляющий 52 разряда за двоичной точкой, поэтому она находится в диапазоне от [0,1) с конечной точностью). Таким образом, фактическое значение представления равно (1)s (1 + m) 2e 1023.
Поскольку мантиссса имеет фиксированную точку и имеет фиксированное количество битов, точность очень конечна. Значение, подобное 1.000000000000000001, и значение, подобное 1.000000000000000002, идентичны для очень многих знаков после запятой и большего количества знаков, чем может содержать мантиссанда с двойной точностью.
Когда вы выполняете сложение или вычитание между очень большим числом и очень маленьким числом (относительно друг друга: в нашем примере 1 является «очень большим»; в качестве альтернативы мы могли бы использовать 1 как очень маленькое значение и выбрать очень большое число). значение 10000000000000000), результирующий показатель степени будет почти полностью определяться очень большим числом, а значение очень маленького числа должно быть соответствующим образом масштабировано. В нашем случае оно делится примерно на 1017; так просто исчезает. Значение не содержит достаточно битов, чтобы различить это.
1
или -1
и логическую экспоненту, которая представляет собой целое число со знаком, но, возможно, было бы более разумно использовать фактический бит знака 0
или 1
и побитовую экспоненту, которая у вас есть. чтобы вычесть 1023
из.) Ах, хорошо. Я думаю, что этого достаточно для целей этого вопроса, но я подумаю, как его можно сделать более точным. (Или не стесняйтесь редактировать его самостоятельно.)
- person ruakh; 18.11.2012