我发现在Ruby中使用整数会导致它们的二进制表示形式大于32位时,它们的行为不同于JS。
a = 144419633058839139324
b = 3903086624
JS:
a >> 0; => 1482555392
b >> 0; => -391880672
红宝石:
a >> 0 => 144419633058839139324
[a].pack('V').unpack('V').first => 1482560508
[b].pack('V').unpack('V').first => 3903086624
我的问题是如何转换我的Ruby代码以提供相同的返回值JS?
这是一个很好的问题。我做了一些实验,试图弄清楚JavaScript到底在做什么,但后来我想:“我敢打赌,规范说。” 果然做到了!
首先,我检查了“按位移位运算符”部分,然后从中学到的知识是您已经知道的:在进行按位运算之前,JavaScript将其操作数转换为32位整数。为此,它链接到名为ToInt32的“抽象操作”(即由JavaScript引擎实现的算法)的定义。令人高兴的是,这很容易理解:
ToInt32 :(带符号的32位整数)
抽象操作ToInt32将其自变量转换为-2 31到2 31 -1(含)范围内的2 32个整数值之一。此抽象操作的功能如下:
我们可以将其直接转换为Ruby(我将步骤1-5标记为注释):
def to_int32(number)
# (1)(2)
begin
sign = number < 0 ? -1 : 1
abs = number.abs
return 0 if abs == 0 || abs == Float::INFINITY
rescue
return 0
end
pos_int = sign * abs.floor # (3)
int_32bit = pos_int % 2**32 # (4)
# (5)
return int_32bit - 2**32 if int_32bit >= 2**31
int_32bit
end
那么,行得通吗?
a = 144419633058839130000
puts to_int32(a)
# => 1482551184
b = 3903086624
puts to_int32(b)
# => -391880672
似乎是合法的!
现在,我敢肯定有更简洁,可能更快的方法来执行此操作,但这应该可以帮助您入门。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句