zim*_*ies 6 ruby bit-manipulation
我想直接访问 ruby 整数的符号位。
Ruby 允许通过[]操作符访问 int 的位:
1[0] -> 1
2[1] -> 1
我尝试过-1[-1](访问最后一个),但这不起作用。
您可以通过查看以下文档来理解这一点Fixnum#[]:
返回fix的二进制表示形式中的第+n+位,其中fix[0]是最低有效位
https://ruby-doc.org/core-2.2.0/Fixnum.html#method-i-5B-5D
AFixnum不是数组,因此它#[]函数的行为可以(并且确实)与您对数组的期望不同。
要访问最高有效位,您可以使用#bit_length - 1
> a = 5
=> 5
> a[a.bit_length - 1]
=> 1
Run Code Online (Sandbox Code Playgroud)
但是,这排除了负数的符号位,因此要获取符号位,请不要从bit_length
> a = -5
=> 5
> a[a.bit_length]
=> 1
> a = 42
=> 42
> a[a.bit_length]
=> 0
Run Code Online (Sandbox Code Playgroud)
您也可以使用< 0比较:
> a = -5
=> -5
> sign_bit = a < 0 ? 1 : 0
=> 1
Run Code Online (Sandbox Code Playgroud)
首先,让我们阅读以下文档#size:
返回 fix 的机器表示形式的字节数。
从函数的实现中我们可以得知,如果存储的数字在 32 位有符号整数的范围内,则将存储为 1。在这种情况下#size返回4. 如果它更大,它将存储在 64 位整数中并#size返回8。
然而,并非所有这些位都在使用中。如果您存储数字5(0b101),您的 32 位将被占用
10100000 00000000 00000000 00000000
Run Code Online (Sandbox Code Playgroud)
负数大多数时候存储为 2 的补码(不确定是否适用于 ruby),这意味着如果您存储该数字,-5您的 32 位将被占用
11011111 11111111 11111111 11111111
Run Code Online (Sandbox Code Playgroud)
因此,您还可以使用以下代码访问符号位:
x[x.size * 8 - 1]
Run Code Online (Sandbox Code Playgroud)
如果你好奇为什么5[-1]不抛出异常并且仍然返回一个数字,你可以查看源代码Fixnum#[](在前面提到的文档页面上)。
if (i < 0) return INT2FIX(0);
Run Code Online (Sandbox Code Playgroud)
0如果您的索引为负数,则仅返回。