Для значения с плавающей запятой a: Does a * 0.0 == 0.0 всегда оценивает true для конечных значений a?

Я всегда предполагал, что следующий тест всегда будет иметь успех для конечных значений (без INF, NAN) somefloat:

assert(somefloat*0.0==0.0);

В Умножение на 0 оптимизация было указано, что double a=0.0 и double a=-0.0 не являются, строго говоря, одной и той же.

Поэтому мне было интересно, может ли это привести к проблемам на некоторых платформах, например. может ли результат вышеуказанного теста зависеть от a от положительного или отрицательного.

Ответ 1

Если ваша реализация использует арифметику IEEE 754 (что больше всего), то положительный и отрицательный ноль будут сравниваться равными. Поскольку левая часть вашего выражения может быть только положительным или отрицательным нулем для конечного a, утверждение всегда будет истинным.

Если он использует какую-то другую арифметику, то может сказать вам только разработчик и, надеюсь, документация по реализации. Можно утверждать (см. Комментарии), что формулировка стандарта может быть принята, чтобы подразумевать, что они должны сравнивать равные в любом случае, и, конечно же, никакая нормальная реализация не сделала бы иначе.

Ответ 2

-0.0 == 0.0 согласно правилам двойного сравнения.

Для не конечных значений (+ -Inf, Nan) somefloat * 0.0!= 0.0.

Ответ 3

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