为什么[float.MaxValue == float.MaxValue + 1]确实返回true?

时间:2010-11-22 23:29:22

标签: c# floating-point overflow

我想知道你是否可以用浮点类型来解释溢出。

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

5 个答案:

答案 0 :(得分:24)

因为1太小而无法减少float.MaxValue值。

任何小于1e32的东西都会低于浮点数的精度,所以它实际上与添加零相同。

编辑:

ulrichb表明,1e23的值确实会影响float.MaxValue,这意味着你根本不会比较浮点数,而是会加倍。在添加和比较之前,编译器会将所有值转换为双精度值。

答案 1 :(得分:9)

这非常有趣:

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

所以,......正如Guffa所说,fMax + 1E23f被转换为加倍,dMax + 1E292d加起来为Infinity

答案 2 :(得分:3)

这里的问题是浮点精度。 float.MaxValue对应于3.40282e + 038f。但是float的精度要低得多,事实上,精度只有7位数。

超出该精度的任何内容都“填充零”,并且为该高数字添加1不会改变它。

答案 3 :(得分:3)

简洁地说,差异在第39位,float只存储前7位(ish)。这是浮点运算的一个特征。

答案 4 :(得分:0)

要使float类型临时变量实际保存单个精度值,必须从内存中的float变量加载它。通常允许编译器表示具有比所需更高精度的单精度值,并且当值在寄存器中时倾向于这样做。当它溢出回内存时,会失去额外的精度。