Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Ruby中模拟int64溢出_Ruby_Integer_Type Conversion - Fatal编程技术网

在Ruby中模拟int64溢出

在Ruby中模拟int64溢出,ruby,integer,type-conversion,Ruby,Integer,Type Conversion,我是一个很长时间的程序员,但对Ruby还不熟悉。我正在尝试移植一个名为CheckRevision的算法,用于在登录到Battle.net的在线游戏服务之前检查游戏文件的完整性 该算法使用给定的公式对文件进行“散列”。在没有枯燥细节的情况下,它不断地修改值a、b和c,这些值都是64位整数,或者在我移植的参考实现中,修改一个Java长的。我的实现在最初的几次迭代中是正确的,但是当int64应该环绕它时,它就变成了BigNum 将FixNum限制为64位的正确方法是什么?或者我应该使用其他类型吗?只要

我是一个很长时间的程序员,但对Ruby还不熟悉。我正在尝试移植一个名为CheckRevision的算法,用于在登录到Battle.net的在线游戏服务之前检查游戏文件的完整性

该算法使用给定的公式对文件进行“散列”。在没有枯燥细节的情况下,它不断地修改值
a
b
c
,这些值都是64位整数,或者在我移植的参考实现中,修改一个Java
长的
。我的实现在最初的几次迭代中是正确的,但是当int64应该环绕它时,它就变成了BigNum


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

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

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

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

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

在某些情况下,即使在64位平台上,64位整数在Ruby MRI内部也表示为bignum(由于实现细节,在64位平台上fixnum的长度仅为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”通常比模运算符快或快。

64位整数在Ruby MRI中表示为bignum,在某些情况下甚至在64位平台上也是如此(由于实施细节,64位平台上的fixnum只有63位长,32位平台上的fixnum只有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”通常比任何平台或语言上的模运算符更快或一样快。

我喜欢它。如果必要的话,位推送应该会使处理签名整数变得更容易。我喜欢它。此外,如果需要,位推送应该使处理有符号整数更容易。