C#中的float / double Math.Round

时间:2019-01-17 12:22:44

标签: c# rounding

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

有人可以解释为什么吗?

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

因此,您可以看到此数字转换为的双精度数实际上比其转换为的浮点数大。因此很明显,不一定要取整为相同的数字,因为开头的数字不是相同。