Reputation: 65
How can I flip the bits of an integer without changing its sign? For example, how can I flip "1010"
(1010) to "0101"
(510)?
Bitwise negative operator results in negative number: ~10
(~0b1010
) → -11
(0b0101
).
Upvotes: 4
Views: 904
Reputation: 168199
If you mean strings, then:
"1010".tr("01", "10") # => "0101"
If you mean numbers, then:
10.to_s(2).tr("01", "10").to_i(2) # => 5
Upvotes: 2
Reputation: 15791
I am not sure if it fits for your needs, but you can just flip binary string char by char like this:
"1010".chars.map { |i| i == "1" ? "0" : "1" }.join #=> "0101"
Upd:
How about this:
a = ~10
(a.bit_length - 1).downto(0).map { |i| a[i] }.join #=> "0101"
Upvotes: 1
Reputation: 114208
You can flip the bits via XOR:
1010 (decimal 10)
XOR 1111 (decimal 15)
= 0101 (decimal 5)
In Ruby:
0b1010 ^ 0b1111 #=> 5
The number of 1's corresponds to the number of bits, therefore you could use:
num = 0b1010
num ^ (1 << num.bit_length) - 1
#=> 5
Upvotes: 13