1

I was looking for a way to flip all of the bits in an arbitrary-sized number (ie: arbitrary number of bits), and thought of just negating it. When I printed out

p ~0b1010 == 0b0101

It said false. I'm probably using the wrong comparison operator though. What's the proper way to check that two binary numbers are equal in representation?

MxLDevs
  • 19,048
  • 36
  • 123
  • 194

1 Answers1

0

One complement is not flipping all bits.

To flip bits, you need to use a xor operation with an argument with the number of bits 1 you want the significance.

Also you can't negate an binary from arbitrary number. You need to define the number of bits you are flipping. This example will show you why:

> 0b000001 ^ 0b1
 => 0 
> 0b000001 ^ 0b11
 => 2 
> 0b000001 ^ 0b111
 => 6 
> 0b000001 ^ 0b1111
 => 14 

What you can do is define that an arbitrary number of bits is the minimum number of bits you need to represent your number. This is most likely not what you want, however, the following code can do this for you:

def negate_arbitrary_number(x)
  # size is the number of significants digits you have on x. 
  size = 0
  while (a >> size) != 0
    size += 1
  end

  # this is the binary with all number 1's on 
  mask = ("1"*size).to_i(2)

  # xor your number
  x ^ mask 
end

or this code:

def negate_arbitrary_number(x)
  x.to_s(2).unpack("U*").map{|x| x == 49 ? 48 : 49}.pack("U*")
end

you might want to do a simple benchmark to test it.

fotanus
  • 19,618
  • 13
  • 77
  • 111
  • So when the wiki article says `swapping 0's for 1's and vice-versa` this is not what is happening in Ruby when I use the `~` operator? – MxLDevs Jun 07 '13 at 04:06
  • That is happening, but the `1` in binary for your computer don't have the bits the way you expected. Computers work with [Two's complement](http://en.wikipedia.org/wiki/Two%27s_complement). Check [this answer](http://stackoverflow.com/a/791340/413494) for a more complete explantion – fotanus Jun 07 '13 at 07:14
  • I think get it. I will specify that the domain of values I am working with is restricted to positive integers only (and usually entered in the form `0b...`, and the only operations I am working with are bit-wise operations (no arithmetics). Given these conditions, it should be sufficient to use the `~` operator to "flip all bits" and correctly perform bit-masking without having to worry about how the computer interprets it? – MxLDevs Jun 07 '13 at 11:11