我想要的:
assert_equal 6, ones_complement(9) # 1001 => 0110
assert_equal 0, ones_complement(15) # 1111 => 0000
assert_equal 2, ones_complement(1) # 01 => 10
输入的大小不是固定的,如 4 位或 8 位。而不是二进制流。
我看到的:
v = "1001".to_i(2) => 9
有点翻转运算符~
(~v).to_s(2) => "-1010"
sprintf("%b", ~v) => "..10110"
~v => -10
我认为它与用于存储标志或其他东西的一位有关......有人可以解释这个输出吗?如何在不诉诸字符串操作的情况下获得一个补码,例如从 sprintf 输出中删除最后 n 个字符以获得“0110”或将 0 替换为 1,反之亦然
最佳答案
Ruby 只存储一个(有符号的)数字。这个数字的内部表示是不相关的:它可能是 FixNum、BigNum 或其他东西。因此,数字中的位数也是不确定的:毕竟它只是一个数字。这与例如 C 相反,其中 int 可能是 32 位(固定)。
那么 ~ 运算符会做什么呢?好吧,就像这样:
class Numeric
def ~
return -self - 1
end
end
...因为在查看 2 的补码时,这就是“~”所代表的。
因此,您的输入语句中缺少的是您要切换的位数:32 位 ~ 与通用 ~ 不同,就像在 Ruby 中一样。
现在,如果你只想对 n 位进行位翻转,你可以这样做:
class Numeric
def ones_complement(bits)
self ^ ((1 << bits) - 1)
end
end
...但是您必须指定要翻转的位数。这不会影响标志标志,因为它超出了 XOR 的范围:)
关于ruby - 如何使用 Ruby 的按位运算符计算一个人的补码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1201681/