在 Ruby 中模拟 int64 溢出

2024-04-24

我是一名资深程序员,但对 Ruby 还很陌生。我正在尝试移植一种名为 CheckRevision 的算法,用于在登录 Battle.net 的在线游戏服务之前检查游戏文件的完整性。

该算法使用给定的公式对文件进行“哈希”。没有无聊的细节,而是不断修改数值a, b and c它们是 64 位整数,或者在我移植的参考实现中,一个 Javalong。我的实现在前几次迭代中是正确的,但是当 int64 应该环绕时,它会变成 BigNum。

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


在某些情况下,即使在 64 位平台上,64 位整数在 Ruby MRI 内部也表示为 Bignum(由于实现细节,Fixnum 在 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。我在这里列出的详细信息可能会或可能不会将此方式应用于其他实现,但二进制“and”通常更快或与任何平台或语言上的模运算符一样快。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 Ruby 中模拟 int64 溢出 的相关文章

随机推荐