我想我的问题也可以这样询问:在双精度变量中,单个十进制值是否可以表示多种方式。
我有一个哈希表实现,双精度浮点数将是键,我使用哈希算法构建哈希,同时迭代双子的每个字节(至少我的系统是64-位,所以哈希8个字节)。我的问题是,如果单个值,比如'1.2345'可以以二进制形式表示为双倍超过1的方式,那么它可能会导致单个值的多个可能的哈希值。
我不确定在哪里研究这种可能性。如果我不得不猜测我会猜测它是不可能的,或者如果有可能某些东西标准化它以确保值在给定系统上总是具有相同的表示。我主要是在寻找确认。
如果某个值可以包含多个表示,那么我需要在对其进行哈希处理之前将其标准化,我希望能够提供有关如何执行此操作的建议。
编辑:
我发现了一些关于浮点数的信息。它们存储为mantessa和exponent。所以我的问题是单个浮点数可以用mantessa和exponent的多个组合来表示。
答案 0 :(得分:2)
IEEE 754二进制浮点只有一个编码用于除零之外的每个可表示值,其中有+0和-0。
今天大多数C实现都使用IEEE 754二进制格式。但是,并非所有实现浮点运算都正确(例如,从字符串中的十进制转换为二进制浮点可能会产生稍微不准确的结果),并且操作链的结果可能与精确算术得到的值不同,并且不同的链可能产生不同的值,即使它们在数学上是相同的。 (后者包括使用不提供严格浮点评估的不同编译器编译相同源代码的结果。)
IEEE 754还指定了十进制浮点格式,并且确实有多个值表示。
答案 1 :(得分:2)
浮点数的字节散列会有两个问题。
第一个经常令人惊讶的是,有两个表示0,一个表示每个可能的符号位。 (0和负0)。这些不仅在数学上相等,而且还要求在C / C ++中测试相等。负0在计算中经常出现,但并非所有printf
都将其打印为-0。 (在Intel硬件上,至少0.0 / -1.0是-0.0。)
所以你需要确保两个零都是相同的。
另一个问题是NaNs。有很多NaN,但它们甚至对自己来说都不具有可比性(技术上),因此它们会产生糟糕的哈希键。可能最简单的解决方案是忽略它们,因为没有人应该期望NaN可用作散列键。但问题是,如果有人试图将一个放入您的哈希表中,然后再将其放入,如果您使用浮点==
检查密钥是否存在,则最终可能会输入两次。因此,一个简单的错误(或故意攻击)可能会通过扩展哈希表来快速耗尽内存。 (如果将字节与memcmp进行比较,则不会出现此问题。)
答案 2 :(得分:0)
有可能。双精度值比浮子更精确,但在精度方面仍然不是100%气密。使用定点或整数对表示(即:值的每个部分的整数)。