所以,我从理论上读到,Ruby中的整数没有最大值,并且它们可以根据需要大小。但是,当我乘以以下是导致负值(我认为这是溢出的迹象?):
44404051714 * 44404051714 => -2081807267335685116
有人可以向我解释一下吗?
答案 0 :(得分:3)
这看起来像Ruby的Fixnum
类乘法实现中的一个错误。查看来源,numeric.c中fixmul
函数中的以下行(严重剪切)突然出现:
...
2645: long a, b;
...
2663: c = a * b;
2664: r = LONG2FIX(c);
...
2667: if (FIX2LONG(r) != c || c/a != b) {
2668: r = rb_big_mul(rb_int2big(a), rb_int2big(b));
...
如果我正确读取它,那是来自正在进行Fixnum
乘法的代码,以及应该进行溢出检测的代码位,以确定结果是否应该实际重新计算为{ {1}}。麻烦的是它是错误的C代码:Bignum
和a
类型为long,如果b
溢出则根据C标准产生未定义的行为。一个好的编译器可以通过假设溢出永远不会发生在正确的C程序中来利用这一点,并且基于该逻辑可以优化掉溢出检查a * b
。
因此,如果您的Ruby版本是使用合理的最新编译器编译的(最近版本的Clang将是一个很好的例子),那可能是导致这种情况的原因。
无论如何,我认为值得一个错误报告:即使这不是你所看到的原因,上面的C代码也是可疑的。
c / a != b
声明。理论上,这应该可以防止溢出检查被优化掉。因此,如果 是问题的原因,那么这将使它成为编译器错误,而不是Ruby代码中的错误。