Bitwise inversion of Bignum

I

Ian Roddis

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?
 
I

Ian Roddis

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.
 
Y

Yukihiro Matsumoto

Hi,

In message "Re: 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.

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

matz.
 
R

Rick DeNatale

Hi,

In message "Re: 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.

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?
 
Y

Yukihiro Matsumoto

Hi,

In message "Re: Bitwise inversion of Bignum"

|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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,770
Messages
2,569,586
Members
45,084
Latest member
HansGeorgi

Latest Threads

Top