Почему [float.MaxValue == float.MaxValue + 1] возвращает true? - PullRequest
28 голосов
/ 23 ноября 2010

Интересно, не могли бы вы объяснить переполнение в типах с плавающей запятой?

float.MaxValue == float.MaxValue + 1 // returns true

Ответы [ 5 ]

24 голосов
/ 23 ноября 2010

Поскольку 1 слишком мал, чтобы образовать вмятину в значении float.MaxValue.

Все, что меньше 1e32, упадет ниже точности поплавка, так что это фактически то же самое, что добавить ноль.

Edit:

ulrichb показал, что значение 1e23 действительно влияет на float.MaxValue, что должно означать, что вы вообще не сравниваете float, а удваиваете. Перед добавлением и сравнением компилятор преобразует все значения в двойные.

9 голосов
/ 23 ноября 2010

Это очень интересно:

float fMax = float.MaxValue;
double dMax = double.MaxValue;

Console.WriteLine("{0}, {1}", fMax == fMax + 1E22f, fMax + 1E22f);
Console.WriteLine("{0}, {1}", fMax == fMax + 1E23f, fMax + 1E23f);

Console.WriteLine("{0}, {1}", dMax == dMax + 1E291d, dMax + 1E291d);
Console.WriteLine("{0}, {1}", dMax == dMax + 1E292d, dMax + 1E292d);

отпечатки:

True, 3.402823E+38
False, 3.402823E+38
True, 1.79769313486232E+308
False, Infinity

Итак, ... как отметил Гуффа, fMax + 1E23f конвертируется в удвоение, а dMax + 1E292d складывается в Infinity.

3 голосов
/ 23 ноября 2010

Вкратце, разница в 39-й цифре, а float хранит только первые 7 (иш). Это характеристика арифметики с плавающей точкой.

3 голосов
/ 23 ноября 2010

Проблема здесь в точности с плавающей точкой. float.MaxValue соответствует 3.40282e + 038f. Но у float точность гораздо меньше, чем на самом деле, точность всего 7 цифр.

Все, что находится за пределами этой точности, «заполнено нулями», и добавление 1 к этому большому числу не изменит его.

0 голосов
/ 19 мая 2014

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

...