我正在迭代一个相当大的数组的 2 个元素的组合。在统计组合的元素时,我发现了一些奇怪的地方。以下示例说明了我的意思:
[1] pry(main)> 10000.times.to_a.combination(2).count
=> 49995000 # correct
[2] pry(main)> 100000.times.to_a.combination(2).count
=> 704982704 # wrong, should be 4999950000
[3] pry(main)> count = 0; 100000.times.to_a.combination(2).each { count+=1 }; count
=> 4999950000 # correct
我使用 wolframalpha 仔细检查了结果:
- 来自 10000 个条目的对 https://www.wolframalpha.com/input/?i=10000!%2F((10000-2)!*2!)
- 来自 100000 个条目的对 https://www.wolframalpha.com/input/?i=100000!%2F((100000-2)!*2!)
我的问题是,为什么 Array#count
在这种情况下不可靠?
另请参阅 https://ruby-doc.org/core-2.2.0/Array.html#method-i-combination和 https://ruby-doc.org/core-2.2.0/Array.html#method-i-count .
非常感谢。
最佳答案
Array#count
不是有问题的方法,Enumerator#count
是:
100000.times.to_a.combination(2).class # => Enumerator
好消息是您遇到的错误在几个月前被报告为 #14805并随后修复,但坏消息是此后没有发布新版本的 CRuby。所以要么等待 2.5.2、2.4.5 等,要么自己编译一个带有修复的版本。
问题是枚举器的计数器被限制为带符号的 32 位整数,因此发生了溢出:
max = (1 << 31) - 1 # max value
4999950000 & max # => 704982704
通过将计数器设置为 bignum(Ruby 的任意精度整数类型,自 2.4 以来是一个内部实现细节)来修复它,以防它的值超出 int
的范围或截至目前unsigned long
.
关于arrays - 为什么 Ruby 的 Array#count 对于大型数组不可靠?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52614440/