.NET Decimal类型计算是确定性的吗?

9
我有两个关于.NET的数据类型确定性的问题:
  1. decimal类型计算是否跨平台确定性?或者换句话说,在所有平台上,对类型执行的数学运算会产生完全相同的结果吗?

  2. 将数字转换为或是否是跨平台确定性的(转换将始终产生完全相同的结果)?


8
在边缘情况下,我看到Mono和Microsoft实现之间可能会有一些差异,这并不让我感到意外。 - Jon Skeet
2
确实,Mono实现中存在一个错误,导致与Windows的结果不同。我会期待其他的。 - Matthew Watson
据我所知,这两个问题的答案都可能是肯定的。但不能保证。然而,在将decimal转换为double时存在一个问题,即与decimal的尾随零有关。可能存在两个仅由尾随零不同的decimal值,因此这两个decimal被认为是相等的(即使它们具有不同的内部表示),因此当您将它们转换为double时,得到的double值是不同的。_另外:_这也证明了转换为double并不总是选择最近的目标。需要示例吗? - Jeppe Stig Nielsen
1
@Bathsheba 举个例子:var a = ((double)200.000000000000000000000M).ToString("R"); var b = ((double)200.0000000000000000000000M).ToString("R"); var c = ((double)200.00000000000000000000000M).ToString("R");。来自于此处的晚回答。由于 System.Decimal 的 GetHashCode() 实现是通过先转换为 double 然后截断一点 double 值,因此在这里涉及到的带小数的 a 甚至有了错误的 decimal.GetHashCode()。其他两个具有正确的哈希码。 - Jeppe Stig Nielsen
不是我所期望的。因此,在.NET中,自定义数字数据类型是获得具有小数部分的跨平台确定性计算的唯一方法。重新发明与该自定义数据类型配套的所有非基本数学运算是更困难的部分,我认为。 - zigzag
显示剩余2条评论
1个回答

0

这个问题的评论中有很多危言耸听。

首先,有人担心过去某个 Mono 的 bug。不仅已经修复了,而且在 2021 年根本不需要使用 Mono。.Net Core 和 .Net5 都是完全跨平台的。

然后还有人担心 GetHashCode 可以为非相等的十进制实例返回相等的值。是的,这就是 GetHashCode(以及所有哈希函数)的工作方式,否则你可以将任意数据类型压缩为 4 个字节。我建议阅读一本关于哈希的书籍,而不是打那么多字。

对于提问者来说,没有必要听取那些人的意见或重新发明 decimal。它是完全安全的。


GetHashCode 可以针对非相等的十进制实例返回 true - Blindy
好的,希望这个澄清能够帮助OP更好地理解decimal的状态。 - Blindy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接