Я знаю, что некоторые значения не могут быть легко определены в числах с плавающей запятой и являются только «аппроксимированными», из-за чего прямые сравнения «равно» часто не работают.
Можно ли точно хранить std::numeric_limits::max в вещественном числе, и будет ли этот код работать должным образом?
float myFloat = std::numeric_limits<float>::max();
//...later...
if(myFloat == std::numeric_limits<float>::max())
{
//...myFloat hasn't changed...
}
operator==
должно датьtrue
, если указанное отношение истинно, иfalse
, если оно ложно. Очевидно, что значение переменной равно самому себе, потому что по определению она содержит то же значение, что и она сама, она не может содержать более одного значения! (Это не относится к значениям NaN, которые всегда возвращают false даже по сравнению с самими собой, но значения NaN особенные) 25.02.2013numeric_limis
не реализуется компилятором, это просто библиотечная функция, которая возвращает число с плавающей запятой. Если значение уже сохранено в вещественном числе, то как его значение может измениться? каждый раз, когда вы вызываете функцию, вы возвращаете одно и то же значение. Если вы присвоите это значениеfloat
значениюfloat
, у вас останется то же самое значение. Даже если функция вернула значение, которое нельзя точно представить (которое она не представляет), например 0,1, каждый раз, когда вы ее вызываете, вы получаете одно и то же значение. 25.02.2013f1==f2
в моем ответе демонстрирует такую ситуацию: двум переменным присваивается одно и то же значение, поэтому они имеют одинаковое значение. 25.02.2013f==f
всегда верно, аcomplicated_expr()==complicated_expr()
очень редко ложно. Многие компиляторы намеренно (gcc -ffast-math
) или случайно иногда позволяют себе выполнять математические операции с плавающей запятой с точностью, отличной от запрошенной. Например, еслиf
содержит0.1
, то не совсем умный компилятор может оптимизироватьf==f
вf==0.1
и выполнить сравнение с двойной точностью (возможно, потому, что это быстрее для любой цели, о которой он больше всего заботится), поэтому в итоге он будет эквивалентно0.1f==0.1
, что неверно. 05.12.2013