我有两个关于.NET的数据类型确定性的问题:
decimal
类型计算是否跨平台确定性?或者换句话说,在所有平台上,对类型执行的数学运算会产生完全相同的结果吗?将数字转换为或是否是跨平台确定性的(转换将始终产生完全相同的结果)?
decimal
类型计算是否跨平台确定性?或者换句话说,在所有平台上,对类型执行的数学运算会产生完全相同的结果吗?
将数字转换为或是否是跨平台确定性的(转换将始终产生完全相同的结果)?
这个问题的评论中有很多危言耸听。
首先,有人担心过去某个 Mono 的 bug。不仅已经修复了,而且在 2021 年根本不需要使用 Mono。.Net Core 和 .Net5 都是完全跨平台的。
然后还有人担心 GetHashCode
可以为非相等的十进制实例返回相等的值。是的,这就是 GetHashCode
(以及所有哈希函数)的工作方式,否则你可以将任意数据类型压缩为 4 个字节。我建议阅读一本关于哈希的书籍,而不是打那么多字。
对于提问者来说,没有必要听取那些人的意见或重新发明 decimal
。它是完全安全的。
GetHashCode
可以针对非相等的十进制实例返回 true
。 - Blindydecimal
的状态。 - Blindy
decimal
转换为double
时存在一个问题,即与decimal
的尾随零有关。可能存在两个仅由尾随零不同的decimal
值,因此这两个decimal
被认为是相等的(即使它们具有不同的内部表示),因此当您将它们转换为double
时,得到的double
值是不同的。_另外:_这也证明了转换为double
并不总是选择最近的目标。需要示例吗? - Jeppe Stig Nielsenvar 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