C# IEEE754 舍入

问题描述 投票:0回答:1

考虑以下 C# 代码...

double x = Math.Round(72.6d, 2, MidpointRounding.ToZero);
double y = Math.Round(82.6d, 2, MidpointRounding.ToZero);

x
变为
72.59
y
变为
82.6

但是为什么呢?通过这个 IEEE754 转换器,看来它们都应该是

.6

我可以通过执行以下操作来解决该问题

(double)Math.Round(Convert.ToDecimal(72.6d), 2, MidpointRounding.ToZero)
。但我更感兴趣的是知道为什么它似乎没有按预期工作的答案。

c# double precision ieee-754
1个回答
0
投票

它必须与浮点数的精度和舍入期间的二进制表示形式与提供的文字值不同。正如您已经发现的,您可以使用十进制代替,它不存在相同的舍入问题。

https://learn.microsoft.com/en-us/dotnet/api/system.math.round?view=netframework-4.7.2#rounding-and- precision

这是文档中的原因部分:

为了判断舍入操作是否涉及中点 值,Round 方法将要四舍五入的原始值乘以 10n,其中 n 是返回值中所需的小数位数 值,然后判断剩余的小数部分是否 该值大于或等于 0.5。这是一个轻微的变化 平等测试,正如“平等测试”中所讨论的 双引用主题的部分,测试与 浮点值是有问题的,因为浮点 格式的二进制表示和精度问题。这意味着 略小于 0.5 的数字的任何小数部分 (由于精度损失)不会向上舍入。

这就是导致这种情况的原因:

舍入中点值的精度问题最有可能 出现在以下情况:

当小数值无法精确表达时 浮点类型的二进制格式。

当要舍入的值是根据一个或多个计算得出时 浮点运算。

当要舍入的值是 Single 而不是 Double 或 十进制。有关详细信息,请参阅下一节“舍入和 单精度浮点值。

© www.soinside.com 2019 - 2024. All rights reserved.