【问题标题】:Why does Ruby hash a FixNum n to 2n+1?为什么 Ruby 将 FixNum n 哈希为 2n+1?
【发布时间】:2012-04-01 17:04:47
【问题描述】:

为什么 Ruby 将整数 n 散列到 2 * n + 1

>> [0,1,2,3].each {|x| puts x.hash}
1
3
5
7

我可以看到您并不总是需要复杂的哈希值,尤其是对于简单的对象。但是,为什么要使用“双加 1”规则而不是执行 Python 所做的,即对整数进行哈希处理?

>>> map(hash,[0,1,2,3])
[0, 1, 2, 3]

有什么原因吗?

【问题讨论】:

  • 你使用的是什么版本的 ruby​​?
  • 我在 Linux 上的 ruby​​19 中得到了非常不同的输出:-4507979699089292723 -2858483109482119521 -3969476086452127319 2371950802045904379
  • ruby 1.8.7 (2010-01-10 patchlevel 249) [universal-darwin11.0]
  • 我也很想知道答案。我可以想到该哈希至少有两个有趣的特征:(1)只要 'n' 不太大,您可以轻松计算给定哈希的原始数字,以及(2)哈希始终设置。如果不同的类型总是散列到低位为零,您可以通过检查该位非常快速地在两种类型之间进行过滤。
  • @oleg 我在 1.9 的 windows 和 mac 上得到了类似的结果

标签: ruby hash


【解决方案1】:

整数是对象,所以它们有一个object_id。但是有无数个整数。看起来,没有其他物体的空间。 Ruby 是如何做到这一点的?

10.times{|i| puts i.object_id}

输出:

1
3
5
7
9
11
13
15
17
19

整数取所有奇数 object_id,其余对象介于两者之间,它们使用偶数。从 object_id(和哈希)到整数(反之亦然)的转换非常简单:砍掉最右边的 1 位(或添加它)。

【讨论】:

  • 所以它基本上是用于对象 id 的 Hilbert's Hotel。 ;-)
  • @Michael Kohl:经过一番思考,Cantor 这个名字出现了。我想这是对他们聪明才智的意想不到的实际使用。
  • 也很有趣:false.object_id == 0; true.object_id == 2; nil.object_id == 4
  • false.hash == 4310718428470363969
猜你喜欢
  • 2017-02-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-29
  • 2011-07-01
  • 1970-01-01
  • 2016-10-23
  • 2011-03-31
相关资源
最近更新 更多