Когда (x == (x + y) -y) или (x == (x-y) + y) гарантируется для плавающих объектов IEEE? - PullRequest
0 голосов
/ 16 января 2019

В C или другом языке, который использует плавающие значения IEEE, у меня есть две переменные x и y, которые гарантированно будут конечными, не-NaN, в основном нормальные числа.

У меня есть некоторый код, который предполагает, по сути, что следующий код не имеет никакого эффекта:

float x = get_x ();
float y = get_y ();

float old_x = x;
x += y;
x -= y;
assert (old_x == x);
x -= y;
x += y;
assert (old_x == x);

Я знаю, что это будет верно для определенных классов значений, то есть тех, которые не имеют "много" значимых цифр в мантиссе, но я хотел бы прояснить крайние случаи.

Например, двоичное выражение 1.3 будет иметь значимые цифры на всем протяжении мантиссы, как и 1.7, и я не должен предполагать, что 1.3+1.7==3 точно, но могу ли я предположить, что если я добавлю такие числа вместе, а затем вычесть их, или наоборот, я верну первое значение снова?

Каковы формальные граничные условия для этого?

1 Ответ

0 голосов
/ 16 января 2019

Количество битов в конвейере с плавающей запятой не является частью стандарта.

Из Википедии:

Стандарт также рекомендует использовать расширенный формат (ы) для выполнения внутренние вычисления с большей точностью, чем требуется для конечный результат, чтобы минимизировать ошибки округления: только стандарт определяет минимальную точность и требования к показателям для таких форматы. 80-битный расширенный формат x87 является наиболее распространенным реализован расширенный формат, отвечающий этим требованиям.

Таким образом, поскольку внутренние форматы можно расширять, не зная, когда внутренние форматы усекаются до стандартных форматов, какой метод округления используется, предположение, что добавление значения с последующим его вычитанием приведет к получению исходного значения, не гарантируется по стандарту.

Для банального случая, который вы разместили, он, вероятно, будет работать большую часть времени.

Тогда есть случай обработки NAN.

Вы можете определить граничные случаи для архитектуры, которую вы используете в настоящее время, но, возможно, проще просто проверить, находится ли текущее значение в пределах допустимой погрешности исходного значения.

...