在Ruby中模拟int64溢出

时间:2011-08-30 21:48:11

标签: ruby integer type-conversion

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

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

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

2 个答案:

答案 0 :(得分:2)

在某些情况下,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。我在此处列出的详细信息可能会或可能不会以这种方式应用于其他实现,但二进制“和”通常比任何平台或语言上的模运算符更快或更快。

答案 1 :(得分:1)

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

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