Integer#to_s(2) works on x86, fails on x86_64

Hello,

Can anyone explain why this is happening?

---- on x86_64 ----

$ ruby -v
ruby 1.8.4 (2005-12-24) [x86_64-linux]

$ irb

2956350890592680056.to_s(2)
RangeError: integer 2956350890592680056 too big to convert to int' from (irb):1:into_s’
from (irb):1
from :0

---- on x86 ----

$ ruby -v
ruby 1.8.4 (2005-12-24) [i486-linux]

$ irb

2956350890592680056.to_s(2)
=> “10100100000111000100010111100010111001001011111011100001111000”

Thanks for your consideration.

Suraj K. wrote:

$ irb
ruby 1.8.4 (2005-12-24) [i486-linux]

$ irb

2956350890592680056.to_s(2)
=> “10100100000111000100010111100010111001001011111011100001111000”

Thanks for your consideration.

It’s way too large to fit into an old-style integer of 32 bits, but it
fits
with two bits to spare in a 64-bit integer. Also, in Ruby, normally an
integer too large for the Fixnum class is automatically converted to a
Bignum, so this error should not have happened.

Try this test:

32.upto(128) do |p|
puts 2 ** p
end

See what happens on both platforms. BTW I am thinking this is an error
in
the x86_64 Ruby code.

Suraj K. schrieb:

Hello,

Can anyone explain why this is happening?

no, but it works here:

[email protected]:~$ irb
irb(main):001:0> 2956350890592680056.to_s(2)
=> “10100100000111000100010111100010111001001011111011100001111000”
irb(main):002:0> quit
[email protected]:~$ ruby -v
ruby 1.8.5 (2006-08-25) [x86_64-linux]

maybe it helps to track the problem.

thanks,
patrick

Paul L. wrote:

See what happens on both platforms. BTW I am thinking this is an error in
the x86_64 Ruby code.

The same Exception is thrown on my machine.

From cpuinfo:
processor : 0
vendor_id : AuthenticAMD
cpu family : 15
model : 47
model name : AMD Athlon™ 64 Processor 3000+
stepping : 2

Operating System is Ubuntu 6.06 LTS.

Ruby version (installed via OS package manager): ruby 1.8.4 (2005-12-24)
[x86_64-linux].

16.upto(128) do |p|
n = 2 ** p
puts("#{p}: #{n}: #{n.class}")
end

shows a conversion at

61: 2305843009213693952: Fixnum
62: 4611686018427387904: Bignum

where to_s(2) fails at p == 31

16.upto(128) do |p|
n = 2 ** p
puts("#{p}: #{n}: #{n.class}")
puts(n.to_s(2))
end

31: 2147483648: Fixnum
RangeError: integer 2147483648 too big to convert to `int’

Stefan

Suraj K.:

$ ruby -v
ruby 1.8.4 (2005-12-24) [x86_64-linux]

$ irb

2956350890592680056.to_s(2)
RangeError: integer 2956350890592680056 too big to convert to `int’

irb> “#{RUBY_VERSION} #{RUBY_PLATFORM} #{RUBY_RELEASE_DATE}”
=> “1.9.0 x86_64-linux 2006-10-16”
irb> 2956350890592680056.to_s(2)
=> “10100100000111000100010111100010111001001011111011100001111000”

irb> “#{RUBY_VERSION} #{RUBY_PLATFORM} #{RUBY_RELEASE_DATE}”
=> “1.8.4 x86_64-linux 2005-12-24”
irb> 2956350890592680056.to_s(2)
RangeError: integer 2956350890592680056 too big to convert to int' from (irb):2:into_s’
from (irb):2

Kalman

Kalman N. wrote:

    from (irb):2:in `to_s'
    from (irb):2

Kalman

Seems on 1.8.5 is ok aswell, so the problem is < 1.8.4

irb(main):001:0> “#{RUBY_VERSION} #{RUBY_PLATFORM} #{RUBY_RELEASE_DATE}”
=> “1.8.5 x86_64-linux 2006-12-04”
irb(main):002:0> 2956350890592680056.to_s(2)
=> “10100100000111000100010111100010111001001011111011100001111000”

On Tue, 05 Dec 2006 23:24:57 +0900, Mihai Vlad wrote:

RangeError: integer 2956350890592680056 too big to convert to int' RangeError: integer 2956350890592680056 too big to convert toint’
=> “1.8.5 x86_64-linux 2006-12-04”
irb(main):002:0> 2956350890592680056.to_s(2)
=> “10100100000111000100010111100010111001001011111011100001111000”

Yep. Here are the relevant changelog entries.

Fri Aug 25 17:15:17 2006 Yukihiro M. [email protected]

    * stable version 1.8.5 released.

Sun Feb 5 21:05:34 2006 Hirokazu Yamamoto [email protected]

    * numeric.c (fix_to_s): removed workaround for radix 2. 

Historically,
rb_fix2str could only handle radix 8, 10, 16. (Rev1.37) But
for now,
it can handle radix 2…36. [ruby-Bugs#3438] [ruby-core:7300]
Sat Feb 4 15:56:37 2006 Hirokazu Yamamoto [email protected]

    * numeric.c (fix_to_s): (2**32).to_s(2) fails with exception 

where
sizeof(int) == 4 < sizeof(long). [ruby-core:7300]

Sat Dec 24 18:58:14 2005 Yukihiro M. [email protected]

    * stable version 1.8.4 released.