我不确定这种说明Stack Overflow问题的非标准方式是好还是坏,但是这里是:
什么是最好的(数学或其他技术)解释为什么代码:
static void Main()
{
decimal[] arr =
{
42m,
42.0m,
42.00m,
42.000m,
42.0000m,
42.00000m,
42.000000m,
42.0000000m,
42.00000000m,
42.000000000m,
42.0000000000m,
42.00000000000m,
42.000000000000m,
42.0000000000000m,
42.00000000000000m,
42.000000000000000m,
42.0000000000000000m,
42.00000000000000000m,
42.000000000000000000m,
42.0000000000000000000m,
42.00000000000000000000m,
42.000000000000000000000m,
42.0000000000000000000000m,
42.00000000000000000000000m,
42.000000000000000000000000m,
42.0000000000000000000000000m,
42.00000000000000000000000000m,
42.000000000000000000000000000m,
};
foreach (var m in arr)
{
Console.WriteLine(string.Format(CultureInfo.InvariantCulture,
"{0,-32}{1,-20:R}{2:X8}", m, (double)m, m.GetHashCode()
));
}
Console.WriteLine("Funny consequences:");
var h1 = new HashSet<decimal>(arr);
Console.WriteLine(h1.Count);
var h2 = new HashSet<double>(arr.Select(m => (double)m));
Console.WriteLine(h2.Count);
}
Run Code Online (Sandbox Code Playgroud)
给出以下"有趣"(显然不正确)的输出:
42 42 40450000 42.0 42 40450000 42.00 42 40450000 …
可能重复:
C#为什么相等的小数会产生不相等的哈希值?
我在我的.NET 3.5应用程序(x86或x64,我试过两个)中遇到了一个问题,其中具有不同数量的尾随零的小数具有不同的哈希码.例如:
decimal x = 3575.000000000000000000M;
decimal y = 3575.0000000000000000000M;
Console.WriteLine(x.GetHashCode());
Console.WriteLine(y.GetHashCode());
Console.WriteLine(x == y);
Console.WriteLine(x.GetHashCode() == y.GetHashCode());
Run Code Online (Sandbox Code Playgroud)
在我的机器上输出以下内容:
1085009409
1085009408
True
False
Run Code Online (Sandbox Code Playgroud)
我认为哈希码的差异是由不同比例因子引起的两个数字的不同内部表示.
虽然我可以通过删除尾随零来解决这个问题,但我总是假设GetHashCode应该为x和y返回相同的值,如果x == y.这个假设是错误的,还是Decimal.GetHashCode的问题?
编辑:要清楚我正在使用Visual Studio 2008 SP1,.NET 3.5的版本.
我有一个类型decimal
的变量,其值为1.0
.我将它保存到SQL Server 2012表的列中,其类型为decimal(10, 8)
.
检索该值后,我看到它是1,但是当我调用时ToString()
,返回的值是"1.00000000"
(见下文).
我意识到8位小数对应于数据库中的数据类型.但是,Entity Framework生成的属性中没有任何属性或任何内容可以为其提供此类行为,因此我不知道这是如何发生的.
以下是我在立即窗口中执行的一些测试:
myDecimal
1
myDecimal.ToString()
"1.00000000"
myDecimal == 1
true
myDecimal == 1.0m
true
Run Code Online (Sandbox Code Playgroud)
正如你在前两次测试中看到的那样,它也不是浮点错误的情况(不是因为十进制是定点而我没想到它,但我不得不尝试它,因为我用完了想法).
知道小数ToString()
是如何产生一个8位小数的字符串?
编辑:为了比较,请查看下面的测试.
1m.ToString()
"1"
Run Code Online (Sandbox Code Playgroud)