如何使用Ruby的按位运算符计算一个补码?

Gis*_*shu 4 ruby bit-manipulation operators

我想要的是:

assert_equal 6, ones_complement(9)   # 1001 => 0110
assert_equal 0, ones_complement(15)  # 1111 => 0000
assert_equal 2, ones_complement(1)   # 01 => 10
Run Code Online (Sandbox Code Playgroud)

输入的大小不固定为4位或8位.而是它的二进制流.

我所看到的:

v = "1001".to_i(2)                 => 9
Run Code Online (Sandbox Code Playgroud)

操作员有点翻转 ~

(~v).to_s(2)                       => "-1010"
sprintf("%b", ~v)                  => "..10110"
~v                                 => -10
Run Code Online (Sandbox Code Playgroud)

我认为它与一个用于存储标志的东西有关...有人可以解释这个输出吗?如何在不采用字符串操作的情况下获得一个补码,例如从sprintf输出中删除最后的n个字符以获得"0110"或将0替换为1,反之亦然

Rut*_*ing 7

Ruby只存储(签名)号码.此数字的内部表示不相关:它可能是FixNum,BigNum或其他内容.因此,数字中的位数也是未定义的:毕竟它只是一个数字.这与例如C相反,其中int可能是32位(固定).

那么〜运算符会做什么呢?好吧,就像这样:

class Numeric
    def ~
        return -self - 1
    end
end
Run Code Online (Sandbox Code Playgroud)

...因为在查看2的补数时,这就是'〜'所代表的.

因此,输入语句中缺少的是要切换的位数:32位〜与泛型不同〜就像在Ruby中一样.

现在,如果您只想要对n位进行位翻转,您可以执行以下操作:

class Numeric
    def ones_complement(bits)
        self ^ ((1 << bits) - 1)
    end
end
Run Code Online (Sandbox Code Playgroud)

...但你必须指定要翻转的位数.这不会影响符号标志,因为那个符号超出了您的XOR :)