ruby - Ruby 1.8.7 中的求幂返回错误答案

标签 ruby bignum exponential

我在 irb 中尝试计算 3**557 时遇到了这个问题。 Ruby 和 MacRuby 都安装在我的 Mac (OS X 10.8) 中。而ruby的版本是1.8.7,MacRuby 0.12(ruby 1.9.2)。 rib 和 macirb 在计算 3**557 时给了我两个不同的答案。 (macirb 是对的。)

$ irb
>> 3**557
=> 54755702179342762063551440788945541007926808765326951193810107165429610423703291760740244724326099993131913104272587572918520442872536889724676586931200965615875242243330408150984753872526006744122187638040962508934109837755428764447134683114539218909666971979603

$ macirb
irb(main):001:0> 3**557
=> 57087217942658063217290581978966727348872586279944803346410228520919738045995056049600505293676159316424182057188730248707922985741467061108015301244570536546607487919981026877250949414156613856336341922395385463291076789878575326012378057561766997352898452974964563

然后我尝试了更大的东西,例如3**5337,这次我得到了同样的答案。

那么,这是 Ruby 1.8.7 中的错误,还是我应该使用另一种方法来计算幂?

最佳答案

在计算时,当数字超出 Fixnum 的范围时,Ruby 应该将 Fixnum 转换为 Bignum。对于旧版本的 Ruby,这会因 ** 运算符而失败:

$ ruby --version
ruby 1.8.7 (2012-02-08 patchlevel 358) [universal-darwin12.0]
$ irb
>> 2 ** 62
=> 4611686018427387904
>> 2 ** 63
=> -9223372036854775808
>> 2 ** 64
=> 0

失败的地方取决于架构的字长。本例中 iMac 上的 64 位字。在内部,Fixnum 被转换为一个长整数,并且运算符用长整数处理。 long 字长溢出,Ruby 通过返回 0 不优雅地处理了这个问题。

请注意 * 运算符可以正常工作(转换为 Bignum),而 ** 失败:

>> a = 2 ** 62
=> 4611686018427387904
>> 2 ** 63
=> -9223372036854775808
>> a * 2
=> 9223372036854775808
>> 2 ** 64
=> 0
>> a * 4
=> 18446744073709551616

迁移到更新版本的 Ruby 将解决此问题。如果您无法迁移到较新的版本,请避免使用大幂次的 Fixnum 和 **。

关于ruby - Ruby 1.8.7 中的求幂返回错误答案,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12009799/

相关文章:

python - Ruby 哈希和 Python 字典有什么区别?

ruby-on-rails - 如何创建动态子域 rails

php - 如何比较PHP中的大数?

java - 为什么 JRuby 不能识别 BigNums 而 Ruby 可以?

complexity-theory - 指数时间复杂度的真实示例

ruby - 为什么括号内的换行符会改变算术结果?

ruby-on-rails - Heroku + Sidekiq + Redis + Puma配置问题

c - 任意精度(bignum)整数的乘法算法

complex-numbers - 如何在 Maxima CAS 中求解指数方程

javascript - jQuery Slider - 变得更快