arrays - 为什么 Ruby 的 Array#count 对于大型数组不可靠?

标签 arrays ruby

我正在迭代一个相当大的数组的 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 仔细检查了结果:

我的问题是,为什么 Array#count 在这种情况下不可靠?

另请参阅 https://ruby-doc.org/core-2.2.0/Array.html#method-i-combinationhttps://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/

相关文章:

ruby - 如何从 ruby​​ 脚本运行 cd 命令/更改文件夹路径

ruby - 将 "yielder"对象传递给 Ruby 的枚举器

javascript - 如何在不重新索引数组键的情况下在 JQuery 中添加和删除数组

C语言,字符数组已损坏(?)

ruby - 当包含在 gemfile 中/在应用程序中需要时, "take over"是如何神奇地变薄的?

ruby-on-rails - 尝试输出模型集合的列

ruby - Ruby 中的数组容量限制

c - 初始化 - C 中的多维数组

javascript - 极其简单的 JavaScript 代码不起作用

c# - 如何在 C# 中检查自定义类数组的相等性?