Проверка на равенство с плавающей точкой и дополнительная точность: может ли этот код не сработать?
Обсуждение началось вмой ответ на другой вопрос, Следующий код определяетмашина эпсилон:
float compute_eps() {
float eps = 1.0f;
while (1.0f + eps != 1.0f)
eps /= 2.0f;
return eps;
}
В комментариях было предложено, чтобы1.0f + eps != 1.0f
Тест может не пройти, потому что стандарт C ++ допускает использование дополнительной точности. Хотя я'зная, что операции с плавающей запятой на самом деле выполняются с более высокой точностью (чем указано в реальных используемых типах), я не согласен с этим предложением.
Я сомневаюсь, что во время операций сравнения, таких как==
или же!=
Операнды не усекаются с точностью до их типа. Другими словами,1.0f + eps
Конечно, можно оценить с точностью вышеfloat
(например,long double
), и результат будет сохранен в регистре, который может вместитьlong double
, Тем не менее, я думаю, что перед выполнением!=
Операция левого операнда будет усечена изlong double
вfloat
следовательно, код никогда не сможет не определитьeps
точно (то есть он никогда не сможет выполнить больше итераций, чем предполагалось).
У меня нетЯ не нашел никакой подсказки по этому конкретному случаю в стандарте C ++. Кроме того, код работает нормально, и яЯ уверен, что при его выполнении используется метод повышенной точности, потому что я не сомневаюсь, что любая современная настольная реализация на самом деле использует дополнительную точность при вычислениях.
Что вы думаете об этом?