在Ruby中模拟int64溢出

我是一名长期的程序员,但对Ruby来说是新手。 我正在尝试移植一个名为CheckRevision的算法,用于在登录Battle.net的在线游戏服务之前检查游戏文件的完整性。

该算法使用给定的公式对文件进行“哈希”。 没有枯燥的细节,它会不断地修改值为64位整数的值abc ,或者在我正在移植的参考实现中修改Java long 。 我的实现对于前几次迭代是正确的,但是当int64应该环绕时,它变成了BigNum。

将FixNum限制为64位的正确方法是什么,或者我应该使用其他类型?

在某些情况下,64位整数在Ruby MRI中表示为Bignums,即使在64位平台上也是如此(由于实现细节,Fixnums在64位平台上只有63位长,在32位平台上长31位)。 因此,使用二进制“和”运算符会更快:

 ruby-1.9.2-p290 :001 > a = 2**128 + 1256231 => 340282366920938463463374607431769467687 ruby-1.9.2-p290 :002 > a & (2 ** 64 - 1) => 1256231 ruby-1.9.2-p290 :003 > a & 0xffffffffffffffff => 1256231 

最后一个变体有点丑陋,但也更快,因为Ruby MRI缺少常量文件夹。 如果你在循环中执行002子句,则每次计算2**64 - 1 )。

Ruby MRI是Ruby的官方(“Matz Ruby实现”)变体,即我们大多数人使用的“普通”Ruby。 我在这里列出的细节可能会或可能不会以这种方式应用于其他实现,但二进制“和”通常比任何平台或语言上的模运算符更快或更快。

只要我们讨论无符号整数,就可以使用模运算符来计算溢出。

 irb(main):001:0> a = 2**128 + 1256231 => 340282366920938463463374607431769467687 irb(main):002:0> a % 2**64 => 1256231