3

我写了一个快速的画布可视化来查看我从 C++ 移植到 JavaScript 的散列算法的分布。

我看到奇怪的行为,无论我如何修改哈希值,0 都存在严重偏差,因为它的选择频率是哈希函数中大多数其他数字的两倍。

您可以在以下位置查看演示:http: //jsfiddle.net/x5L73/2/

和原始的 C++ 算法:http ://www.azillionmonkeys.com/qed/hash.html

我所指的代码部分位于 jsFiddle 的底部:

// hash is 0 twice as often as anything else
var hash = app.Hash( word ) % ( 3499 )
  ,   b1 = 0|hash / 59
  ,   b2 =   hash % 59;

对我来说奇怪的是,它为零的频率是任何hash其他值的两倍,无论我选择什么来修改它。在此示例中,它是零次,而任何其他数字都是命中次数。这是通过蛮力测试确定的:1/34991/6998

if( hash!==1234 ){ nonZero++; }else{ zero++ } // 1234 is a random number to check       
if( Math.random() < .00001 ){ console.log( zero, nonZero, 0|nonZero/zero ); }

我在这里想念什么???

4

1 回答 1

4

尽管这是一个非常有趣的事实,在处理整数时可能会派上用场,就像哈希一样,但错误并不是由于 JavaScript有负零这一事实......

OP报告的原始原因是:

这是因为我不小心丢弃了可视化中的所有负数。

是的,负数并不是那么微不足道,我们的大脑有时会忽略它们——尤其是当他们长时间专注于涉及整数的特定困难问题时,就像试图找出好的散列方法,然后切换到看似更简单的任务:显示结果......

所以真正的答案是:除了负零之外,JavaScript 也有更多的负数……不要忘记把它们算在内——即使是在简单的可视化任务中。

TL;博士

我把它留在这里,因为这可能对将来遇到类似问题的人派上用场,因为它可能会导致类似的情况。

看这个问题:+0 and -0 in JavaScript (negative zero and positive zero in JavaScript)

引用:

JavaScript 使用IEEE 745 标准来表示数字。来自维基百科

带符号的零是带有关联符号的零。在普通算术中,-0 = +0 = 0。然而,在计算中,一些数字表示允许存在两个零,通常表示为-0(负零)+0(正零)。这发生在整数的一些有符号数表示和大多数浮点数表示中。数字 0 通常编码为 +0,但可以用 +0 或 -0 表示。

浮点算术的 IEEE 754 标准(目前由支持浮点数的大多数计算机和编程语言使用)需要 +0 和 -0。零可以被认为是扩展实数线的变体,使得 1/-0 = -∞ 和 1/+0 = +∞,除以零仅在 ±0/±0 和 ±∞/±∞ 时未定义.

于 2013-03-06T09:06:42.230 回答