gpt4 book ai didi

C# IEEE754 舍入

转载 作者:行者123 更新时间:2023-12-03 07:50:33 29 4
gpt4 key购买 nike

考虑以下 C# 代码...

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

x 变为 72.59y 变为 82.6

但是为什么呢?按照这个IEEE754 convertor ,两者的小数部分相同。那么为什么他们不给出相同的结果呢?

我可以通过执行以下操作来解决此问题(double)Math.Round(Convert.ToDecimal(72.6d), 2, MidpointRounding.ToZero)。但我更感兴趣的是知道为什么它似乎没有按预期工作的答案。

最佳答案

Microsoft documentation , MidpointRounding.ToZero不进行“中点舍入”。看来微软在这里搞砸了界面:

  • MidpointRounding最初创建为一个枚举,用于在四舍五入到最接近且与偶数 ( ToEven ) 和四舍五入到最接近且远离零 ( AwayFromZero ) 之间进行选择。
  • 后来,Math.Round 中添加了额外的舍入方法。 :向负无穷大舍入 ( ToNegativeInfinity )、向正无穷大舍入 ( ToPositiveInfinity ) 和向零舍入 ( ToZero )。请注意,这些方向不会四舍五入到最接近的方向;他们转向其中一个方向。例如,使用 ToZero 、3.1、3.2、3.5、3.6 和 3.8 均四舍五入为 3。
  • 而不是使用新名称创建新枚举,例如 RoundingMethod ,Microsoft 将这些新值添加为 MidpointRounding 中的成员.

结果是所有五种舍入方法的名称均采用 MidpointRounding.<i>Name</i> 形式。即使其中只有两个是与中点相关的舍入到最近的方法。

(我们还发现使用 To 而不是 Toward 时术语不敏感。3.4 舍入为 3,即朝零舍入。它不会舍入到零。IEEE 754 对这些舍入方法使用“向”。)

除此之外,this documentation告诉我们Math.Round通过乘以 10n 并舍入为整数来进行运算,而不是对原始数字进行正确的舍入判断,我们可以看到会发生什么:

  • 72.6 转换为 double ,产生最接近的可表示值 72.599999999999994315658113919198513031005859375。乘以 100,得到 7259.9999999999990905052982270717620849609375。向零方向舍入为整数,得到 7259。除以 100,得到 72.590000000000003410605131648480892181396484375,如果使用的位数少于 17 个,则打印为 72.59。
  • 82.6 转换为 double ,生产82.599999999999994315658113919198513031005859375。乘以 100,得到 8260。这种情况与之前的情况之间的差异是由于实数相对于可表示数所处的位置的偶然性。然后将 8260 除以 100,得到 82.599999999999994315658113919198513031005859375,如果使用的数字少于 16 位,则打印为 82.60。

关于C# IEEE754 舍入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/77251808/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com