Когда переменная float выходит за пределы поплавка, что происходит?
Я заметил две вещи:
Почему это различие? Получает ли 1 или 2 значение OVERFLOW и, следовательно, поведение undefined?
Изменить: Код для тестирования:
1.
float d = std::numeric_limits<float>::max();
float q = d + 100;
cout << "q: " << q << endl;
2.
float d = std::numeric_limits<float>::max();
float q = d + (d/3);
cout << "q: " << q << endl;
Ответы
Ответ 1
Формально поведение undefined. На машине с IEEE
с плавающей точкой, однако, переполнение после округления приведет к
в Inf
. Однако точность ограничена, и результаты
после округления FLT_MAX + 1
FLT_MAX
.
Вы можете увидеть тот же эффект со значениями в FLT_MAX
.
Попробуйте что-то вроде:
float f1 = 1e20; // less than FLT_MAX
float f2 = f1 + 1.0;
if ( f1 == f2 ) ...
if
будет оцениваться как true
, по крайней мере, с арифметикой IEEE.
(Существуют, или, по крайней мере, существуют машины, где
float
имеет достаточную точность для if
для оценки
false
, но сегодня они не очень распространены.)
Ответ 2
Это зависит от того, что вы делаете. Если "переполнение" поплавка приходит в выражении, которое возвращается непосредственно, то есть
return std::numeric_limits::max() + std::numeric_limits::max();
операция может не привести к переполнению. Я цитирую из стандарта C [ISO/IEC 9899: 2011]:
Оператор return не является присваиванием. Ограничение перекрытия подпункт 6.5.16.1 не применяется к случаю возврата функции. представление значений с плавающей запятой может иметь более широкий диапазон или точность, чем подразумевается типом; литой можно использовать для удаления этого дополнительный диапазон и точность.
Подробнее см. здесь.