float ff = (float)31.15;
double dd = 31.15;
var frst = Math.Round(ff, 1, MidpointRounding.AwayFromZero);
var drst = Math.Round(dd, 1, MidpointRounding.AwayFromZero);
第一:31.1
drst:31.2
有人可以解释为什么吗?
答案 0 :(得分:27)
好吧,$dir = "k:\test"
CD $dir
Get-ChildItem -Recurse |
Where-Object {$_.Name -match '.'} |
Rename-Item -NewName { $_.Name -replace '.',' '}
想要Math.Round
,而不是double
,这就是为什么
float
等于
Math.Round(ff, 1, MidpointRounding.AwayFromZero);
如果我们检查Math.Round((double)ff, 1, MidpointRounding.AwayFromZero);
的值
(double)ff
我们将看到实际的向上错误
Console.Write(((double)ff).ToString("R"));
最后,如预期的那样31.149999618530273
答案 1 :(得分:12)
在浮点中,所有数字在内部均以小数表示,其中分母为2的幂。
(这与小数实际上是具有10的幂的分母的分数类似。所以31.15
只是写分数3115/100
的一种方式)
在浮点中,31.15
必须在内部以二进制数字表示。最接近的二进制分数是:1111.1001001100110011001100110011001100110011001100110011001100...repeating
1100
重复出现(永远重复),因此该数字将被截断,具体取决于它是以double还是float形式存储。浮点数会被截断为24位数字,双精度数将被截断为53位。
Exact: 1111.100100110011001100110011001100110011001100110011001100110011001100...forever
Float: 1111.10010011001100110011
Double: 1111.1001001100110011001100110011001100110011001100110
因此,您可以看到此数字转换为的双精度数实际上比其转换为的浮点数大。因此很明显,不一定要取整为相同的数字,因为开头的数字不是相同。