如何访问ruby整数的符号位?

时间:2016-09-28 17:18:01

标签: ruby bit-manipulation

我想直接访问ruby integer的符号位。

Ruby允许通过[]运算符访问int的位: 1[0] -> 1 2[1] -> 1

我尝试-1[-1](访问最后一个),但这不起作用。

1 个答案:

答案 0 :(得分:3)

您可以通过查看Fixnum#[]的文档来理解这一点:

  

返回fix的二进制表示中的第+ n +位,其中fix [0]是最低有效位

https://ruby-doc.org/core-2.2.0/Fixnum.html#method-i-5B-5D

Fixnum不是一个数组,因此它的#[]函数可以(并且确实)与您期望从数组中得到的行为不同。

解决方案1 ​​

要访问最重要的位,您可以使用#bit_length - 1

> a = 5
=> 5
> a[a.bit_length - 1]
=> 1

然而,这排除了负数的符号位,因此要获取符号位,请不要从bit_length

中删除1
> a = -5
=> 5
> a[a.bit_length]
=> 1
> a = 42
=> 42
> a[a.bit_length]
=> 0

解决方案2

您也可以使用< 0比较:

> a = -5
=> -5
> sign_bit = a < 0 ? 1 : 0
=> 1

解决方案3

首先,让我们阅读#size的文档:

  

返回修复的机器表示中的字节数。

从函数的实现中我们可以收集到,如果存储的数字在32位有符号整数的边界内,如果存储在一个中。在这种情况下,#size会返回4。如果它更大,它将存储在64位整数中,#size将返回8

然而,并非所有这些位都在使用中。如果存储数字5(0b101),则32位将被占用

10100000 00000000 00000000 00000000

负数大部分时间都存储为2s补码(不确定是否适用于ruby),这意味着如果存储数字-5,则32位将被占用

11011111 11111111 11111111 11111111

因此,您还可以使用以下代码访问符号位:

x[x.size * 8 - 1]

加成

如果您对5[-1]未抛出异常并仍然返回数字的原因感到好奇,您可以查看Fixnum#[]的源代码(在前面提到的文档页面上)。

if (i < 0) return INT2FIX(0);

如果您的索引为负数,则只返回0