简体   繁体   English

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

[英]Why [float.MaxValue == float.MaxValue + 1] does return true?

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

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

Because the 1 is way too small to make a dent in the float.MaxValue value. 因为1太小而不能在float.MaxValue值中产生凹痕。

Anything less than 1e32 will fall below the precision of the float, so it's in effect the same as adding a zero. 小于1e32的任何东西都将低于浮点数的精度,因此它实际上与添加零相同。

Edit: 编辑:

ulrichb showed that a value of 1e23 does actually affect float.MaxValue, which has to mean that you are not comparing floats at all, but doubles. ulrichb表明,1e23的值确实会影响float.MaxValue,这意味着你根本不会比较浮点数,而是加倍。 The compiler converts all values to doubles before adding and comparing. 编译器在添加和比较之前将所有值转换为双精度值。

That's very interesting: 这很有趣:

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);

prints: 打印:

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

So, ... as Guffa noted fMax + 1E23f is converted to double and dMax + 1E292d adds up to Infinity . 所以,......正如Guffa所说, fMax + 1E23f转换为double, dMax + 1E292d加起来为Infinity

The problem here is floating point precision. 这里的问题是浮点精度。 float.MaxValue corresponds to 3.40282e+038f. float.MaxValue对应于3.40282e + 038f。 But a float has much less precision that, in fact, there are only 7 digits of precision. float精度要低得多,事实上,精度只有7位数。

Anything beyond that precision is "filled with zeros", and adding 1 to that high number will not change it. 超出该精度的任何东西都是“用零填充”,并且向该高数字添加1将不会改变它。

Succinctly, the difference is in the 39th digit, and float only stores the first 7 (ish). 简而言之,差异在第39位,而float只存储前7位(ish)。 This is a characteristic of floating-point arithmetic. 这是浮点运算的一个特征。

To get a float type temporary variable to actually hold a single precision value, it must have been loaded from a float variable in memory. 要使float类型的临时变量实际保存单个精度值,必须从内存中的float变量加载它。 The compiler is generally allowed to represent single-precision values with more precision than required, and tends to do so while the value is in a register. 通常允许编译器表示具有比所需更高精度的单精度值,并且当值在寄存器中时倾向于这样做。 When it spills back to memory the extra precision is lost. 当它溢出回内存时,会失去额外的精度。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM