Math.Round()是否生成可靠的哈希值

时间:2014-05-16 13:38:11

标签: c# .net hash double rounding

将Math.Round(double,int)的结果与==进行比较是否保存,并将其用作HashSet<Double>GroupBy(d=>Math.Round(d,1))的键?

换句话说,是否存在以下断言失败的双精度x和y?

double x = ...;
double y = ...;
double xRound = Math.Round(x, 1);
double yRound = Math.Round(y, 1);

Debug.Assert(xRound==yRound || Math.Abs(xRound-yRound)>=0.1);

假设我想将一份双打列表分组:

List<double> values = ...;
List<double> keys = values.GroupBy(d=>Math.Round(d,1)).Select(kv=>kv.Key).ToList();

我是否有机会获得值为0.100000000的密钥和另一个值为0.09999999999的密钥?

(我尝试解析反汇编的网络框架Math.cs源代码,但Round()最终会调用本机函数。)

1 个答案:

答案 0 :(得分:1)

通常,给定相同的起始值和相同的操作,将获得相同的结果。

但是,如果你(例如)做了:

double d1 = 10;
d1 /= 0.1;
double d2 = 25;
d2 /= 0.25;

然后您可能会发现d1d2没有相同的值(因为IEEE754可以完全代表0.25,但不是 {{1} }。

所以,考虑到这一点以及人们似乎有浮点数的相当多的问题,我会说你最好的选择是选择不同的哈希方法。