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:in `to_s'
        from (irb):1

---- on x86 ----

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

$ irb

2956350890592680056.to_s(2)

=> "10100100000111000100010111100010111001001011111011100001111000"

Thanks for your consideration.

···

from :0

--
Posted via http://www.ruby-forum.com/\.

Suraj Kurapati wrote:

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:in `to_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.

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.

···

--
Paul Lutus
http://www.arachnoid.com

Suraj Kurapati schrieb:

Hello,

Can anyone explain why this is happening?

no, but it works here:

patrick@Dragon:~$ irb
irb(main):001:0> 2956350890592680056.to_s(2)
=> "10100100000111000100010111100010111001001011111011100001111000"
irb(main):002:0> quit
patrick@Dragon:~$ ruby -v
ruby 1.8.5 (2006-08-25) [x86_64-linux]

maybe it helps to track the problem.

thanks,
  patrick

Suraj Kurapati:

$ 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'

"#{RUBY_VERSION} #{RUBY_PLATFORM} #{RUBY_RELEASE_DATE}"

  => "1.9.0 x86_64-linux 2006-10-16"

2956350890592680056.to_s(2)

  => "10100100000111000100010111100010111001001011111011100001111000"

"#{RUBY_VERSION} #{RUBY_PLATFORM} #{RUBY_RELEASE_DATE}"

  => "1.8.4 x86_64-linux 2005-12-24"

2956350890592680056.to_s(2)

RangeError: integer 2956350890592680056 too big to convert to `int'
        from (irb):2:in `to_s'
        from (irb):2

Kalman

Paul Lutus wrote:

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.

The same Exception is thrown on my machine.

From cpuinfo:
processor : 0
vendor_id : AuthenticAMD
cpu family : 15
model : 47
model name : AMD Athlon(tm) 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

Kalman Noel wrote:

Suraj Kurapati:
  

$ 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'
    
> "#{RUBY_VERSION} #{RUBY_PLATFORM} #{RUBY_RELEASE_DATE}"
  => "1.9.0 x86_64-linux 2006-10-16"
> 2956350890592680056.to_s(2)
  => "10100100000111000100010111100010111001001011111011100001111000"

> "#{RUBY_VERSION} #{RUBY_PLATFORM} #{RUBY_RELEASE_DATE}"
  => "1.8.4 x86_64-linux 2005-12-24"
> 2956350890592680056.to_s(2)
RangeError: integer 2956350890592680056 too big to convert to `int'
        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"

···

--
Andi

Kalman Noel wrote:

Suraj Kurapati:
  

$ 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'
    
> "#{RUBY_VERSION} #{RUBY_PLATFORM} #{RUBY_RELEASE_DATE}"
  => "1.9.0 x86_64-linux 2006-10-16"
> 2956350890592680056.to_s(2)
  => "10100100000111000100010111100010111001001011111011100001111000"

> "#{RUBY_VERSION} #{RUBY_PLATFORM} #{RUBY_RELEASE_DATE}"
  => "1.8.4 x86_64-linux 2005-12-24"
> 2956350890592680056.to_s(2)
RangeError: integer 2956350890592680056 too big to convert to `int'
        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"

Yep. Here are the relevant changelog entries.

···

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

Fri Aug 25 17:15:17 2006 Yukihiro Matsumoto <matz@ruby-lang.org>

        * stable version 1.8.5 released.

Sun Feb 5 21:05:34 2006 Hirokazu Yamamoto <ocean@m2.ccsnet.ne.jp>

        * 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 <ocean@m2.ccsnet.ne.jp>

        * 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 Matsumoto <matz@ruby-lang.org>

        * stable version 1.8.4 released.

--
Ken Bloom. PhD candidate. Linguistic Cognition Laboratory.
Department of Computer Science. Illinois Institute of Technology.
http://www.iit.edu/~kbloom1/