Bitwise inversion of Bignum

A bitwise inversion of a Bignum sometimes yields odd results. As tested
in 1.8.5:

./ruby -v

ruby 1.8.5 (2006-08-25) [i686-linux]
./ruby -e 'a= “7fffff00”.hex ; b= “ffffff00”.hex ; printf “%b => %b\n”,
a, ~a ;

printf “%b => %b\n”, b, ~b’
1111111111111111111111100000000 => …10000000000000000000000011111111
11111111111111111111111100000000 => …1

In the first case, the ‘…1’ is expected, as per the documentation, but
annoying. Generally when I need to invert a number, I expect a result of
the same length as the original. Since ruby number classes are
inherently variable length I could not rely on the non-significant bits
even if I wanted to. Is it possible to put in a vote for a Bignum ~
operation to return a value of the same length as the largest argument?

The second case is just bizzare. Is this a bug?

This seems to be a problem with inverting any 32 bit number. After
looking at the source, the fix_rev() function in numeric.c performs a
shift-right before inverting, causing an overflow in many cases.

Hi,

In message “Re: Bitwise inversion of Bignum”
on Tue, 24 Oct 2006 22:49:24 +0900, Ian Roddis
[email protected] writes:

|A bitwise inversion of a Bignum sometimes yields odd results. As tested
|in 1.8.5:
|
|./ruby -v
|
|ruby 1.8.5 (2006-08-25) [i686-linux]
|./ruby -e ‘a= “7fffff00”.hex ; b= “ffffff00”.hex ; printf “%b => %b\n”,
|a, ~a ;
|
|printf “%b => %b\n”, b, ~b’
|1111111111111111111111100000000 => …10000000000000000000000011111111
|11111111111111111111111100000000 => …1
|
|In the first case, the ‘…1’ is expected, as per the documentation, but
|annoying.

Both of them are as expected from my view point. What did you expect?

						matz.

On 10/26/06, Yukihiro M. [email protected] wrote:

|ruby 1.8.5 (2006-08-25) [i686-linux]
Both of them are as expected from my view point. What did you expect?
Perhaps I don’t understand:

irb(main):01:0> sprintf(“%b”, “ffffff00”.hex) =>
“11111111111111111111111100000000”

irb(main):02:0> “ffffff00”.hex => 4294967040
So this is a positive number and the 2’s complement representation
should have all zeroes in the msb’s.

So shouldn’t
sprintf(“%b”, ~(“ffffff00”.hex))

give something like:

…100000000000000000000000011111111

What am I missing?


Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/

Hi,

In message “Re: Bitwise inversion of Bignum”
on Fri, 27 Oct 2006 00:15:57 +0900, “Rick DeNatale”
[email protected] writes:

|So shouldn’t
|sprintf(“%b”, ~(“ffffff00”.hex))
|
|give something like:
|
|…100000000000000000000000011111111
|
|What am I missing?

Oh, I was looking at wrong place. It is a bug. I will fix it soon.

						matz.