【问题标题】:Are .NET Decimal type computations deterministic?.NET Decimal 类型计算是确定性的吗?
【发布时间】:2017-01-13 16:20:18
【问题描述】:

我有两个关于 .NET 的 decimal 数据类型确定性的问题:

  1. decimal 类型的计算是跨平台确定性的吗?或者换句话说,decimal 类型的数学运算会在所有平台上产生完全相同的结果吗?

  2. decimal 数字转换为floatdouble 是否具有跨平台确定性(转换总是会产生完全相同的结果)?

【问题讨论】:

  • 看到 Mono 和 Microsoft 实现之间的极端案例存在一些差异,我一点也不感到惊讶......
  • 确实,there was a bug in the Mono implementation 与 Windows 相比导致了不同的结果。我会期待其他人。
  • 据我所知,这两个问题的答案都可能是肯定的。没有保证。但是,与decimal 的尾随零相关的转换为double 存在问题。可能有两个 decimal 值仅在尾随零的数量上有所不同,因此这两个 decimals 被认为是相等的(即使它们具有不同的内部表示),因此当您将它们转换为 @987654333 @,得到的 double 值是不同的。 补充: 这也证明了转换为double 并不总是选择最近的目的地。想要例子吗?
  • 看到一个例子确实很好:这对我来说听起来不对。
  • @Bathsheba 一个例子:var a = ((double)200.000000000000000000000M).ToString("R"); var b = ((double)200.0000000000000000000000M).ToString("R"); var c = ((double)200.00000000000000000000000M).ToString("R");。取自late answer here。因为System.DecimalGetHashCode() 实现首先转换为double,然后稍微截断double,所以这里a 中涉及的小数点甚至有错误的decimal.GetHashCode()。另外两个有正确的哈希码。

标签: .net floating-point type-conversion decimal deterministic


【解决方案1】:

cmets 对这个问题有很多恐惧。

首先,人们担心过去某个时候会出现某个 Mono 错误。这不仅已经修复,而且只是不要在 2021 年使用 Mono。 .Net Core 和 .Net5 都是完全跨平台的。

然后担心GetHashCode 可以为不相等的十进制实例返回相等的值。是的,这就是GetHashCode(实际上是所有哈希函数)的工作方式,否则您可以将任意数据类型压缩为 4 个字节。我建议您阅读有关散列的书,而不是全部输入。

对于 OP,没有必要听那些人的意见或重新发明decimal。使用起来非常安全。

【讨论】:

  • GetHashCode can return true for non-equal decimal instances 无需改写。重读?
  • 好吧,希望澄清有助于 OP 更好地了解 decimal 的状态。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-13
  • 2016-07-20
  • 1970-01-01
  • 2014-05-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多