Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/321.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么[float.MaxValue==float.MaxValue+;1]返回true?_C#_Floating Point_Overflow - Fatal编程技术网

C# 为什么[float.MaxValue==float.MaxValue+;1]返回true?

C# 为什么[float.MaxValue==float.MaxValue+;1]返回true?,c#,floating-point,overflow,C#,Floating Point,Overflow,我想知道你是否可以用浮点类型来解释溢出 float.MaxValue == float.MaxValue + 1 // returns true 因为1太小,无法在float.MaxValue值上留下凹痕 任何小于1e32的值都将低于浮点的精度,因此它实际上与添加零相同 编辑: ulrichb表明1e23的值实际上会影响float.MaxValue,这意味着您根本没有比较float,而是比较double。编译器在添加和比较之前将所有值转换为双精度。这里的问题是浮点精度浮点。最大值对应于3.40

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

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

因为
1
太小,无法在
float.MaxValue
值上留下凹痕

任何小于1e32的值都将低于浮点的精度,因此它实际上与添加零相同

编辑:
ulrichb表明1e23的值实际上会影响float.MaxValue,这意味着您根本没有比较float,而是比较double。编译器在添加和比较之前将所有值转换为双精度。

这里的问题是浮点精度<代码>浮点。最大值对应于3.40282e+038f。但是
浮点
的精度要低得多,事实上,只有7位精度


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

这非常有趣:

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 正确,3.402823E+38 假,3.402823E+38 正确,1.79769313486232E+308 错误,无限
所以。。。正如Guffa所指出的那样,
fMax+1E23f
被转换为双精度,
dMax+1E292d
加起来等于
无穷大
,简单地说,差值在第39位,而
float
只存储前7位(ish)。这是浮点运算的一个特点。

要获取浮点型临时变量以实际保存单个精度值,它必须是从内存中的浮点变量加载的。编译器通常允许以比所需精度更高的精度来表示单精度值,并且倾向于在值位于寄存器中时这样做。当它溢出到内存中时,额外的精度就会丢失。

我想这也是为什么无穷大+1仍然是无穷大的原因。@Blindy:不。更像是海啸中的眼泪。我认为有必要指出(因为到目前为止我还没有在任何答案中看到)浮点(或双精度或十进制)的精度取决于值本身和“7位精度”只是相对较小值的一种启发式。例如,浮点值非常精确,接近0。另一方面,双精度(如IEEE-754,64位)只能表示大约2^53的所有整数,这远远小于它的整个范围。@pst:它是7个有效数字。相对精度。绝对精度,如你所说,取决于值(特别是指数),这在一般的科学记数法中是正确的。@Ben Voight,我的措词有误:“小数点后7位数字”虽然不是严格意义上的正确数字,但我本应该这样写;这是为了强调为什么一个人需要一个“更大的1”“对较大的浮点值进行更改。但如果非常快速且经常添加1会怎么样?”@kenny&Blindy:即使经常添加非常大的值1,仍然无法达到1e32。您可能无法获得高于1e12左右的高度。:)你可能需要一个更好的1。嗯。。。它不是“用零填充”,超过1.3x10³是“用零填充”。无法在所使用的数据类型中表示加法的结果。。。结果中的有效位数比浮点数要多得多,因此得出的结论是,在加法和比较之前,编译器会将所有浮点值转换为双精度。@Guffa:这不会让我感到惊讶。我看到了C++程序中的版本错误,是因为编译器将所有中间结果保存在80位FPU寄存器中。@ Guffa:我不这么认为,因为同样的代码适用于<代码>双< />代码(编辑答案)。如果检查最大值和阈值之间的差异,您可以看到,上面的float和double操作大致相同。这支持浮点数操作是使用double完成的结论。