Ruby 1.8.1: Unexpected "pack" result


(Dale Martenson) #1

I noticed something that does seem correct. In an application I have been
shipping, I pack value in order to perform IOCTL calls against a device. I
hit a problem when using Ruby 1.8.1. The following worked in 1.6.7 and
1.8.0:

      [ 0xFFFFFFFF ].pack("i")

In 1.8.1, this raises a “Range Error: bignum to big to convert into ‘int’”.

I understood that an “i” designator meant a signed native integer (32-bits).
I don’t see why this should fail.

Also, if I use the “l” designator to indicate a signed long integer (again
32-bits). Everything works.

      [ 0xFFFFFFFF ].pack("l")

Shouldn’t “i” and “l” act the same if the native size of an integer is
32-bits?


(Yukihiro Matsumoto) #2

Hi,

···

In message “Ruby 1.8.1: Unexpected “pack” result” on 04/02/19, Dale Martenson dmartenson@multitech.com writes:

     [ 0xFFFFFFFF ].pack("i")

In 1.8.1, this raises a “Range Error: bignum to big to convert into ‘int’”.

Fixed in the CVS HEAD.

						matz.

(Ara.T.Howard) #3

well, it looks like the orginal code was the problem:

~ > cat int_max.rb

require 'tmpdir'
require 'ftools'

c_prog = <<-code
  #include <limits.h>
  main(){int i = INT_MAX; write(1,&i,sizeof(int));}
code

tmp = Dir::tmpdir

a_c = File.join tmp, 'a.c' 
a_out = File.join tmp, 'a.out' 
out = File.join tmp, 'out' 

open(a_c, 'w'){|f| f.write c_prog}
system "cc #{ a_c } -o #{ a_out }"
system "#{ a_out } > #{ out }"

int_max = IO.read(out).unpack('i').first

p(int_max)
p((2 ** 31) - 1)
p(0xFFFFFFFF)
p((2 ** 32) - 1)


File.rm_f a_c
File.rm_f a_out
File.rm_f out

~ > ruby int_max.rb

2147483647
2147483647
4294967295
4294967295

you only get 31 bits for signed ints.

-a

···

On Thu, 19 Feb 2004, Dale Martenson wrote:

Date: Thu, 19 Feb 2004 00:05:53 +0900
From: Dale Martenson dmartenson@multitech.com
Newsgroups: comp.lang.ruby
Subject: Ruby 1.8.1: Unexpected “pack” result

I noticed something that does seem correct. In an application I have been
shipping, I pack value in order to perform IOCTL calls against a device. I
hit a problem when using Ruby 1.8.1. The following worked in 1.6.7 and
1.8.0:

      [ 0xFFFFFFFF ].pack("i")

In 1.8.1, this raises a “Range Error: bignum to big to convert into ‘int’”.

I understood that an “i” designator meant a signed native integer (32-bits).
I don’t see why this should fail.

Also, if I use the “l” designator to indicate a signed long integer (again
32-bits). Everything works.

      [ 0xFFFFFFFF ].pack("l")

Shouldn’t “i” and “l” act the same if the native size of an integer is
32-bits?

EMAIL :: Ara [dot] T [dot] Howard [at] noaa [dot] gov
PHONE :: 303.497.6469
ADDRESS :: E/GC2 325 Broadway, Boulder, CO 80305-3328
URL :: http://www.ngdc.noaa.gov/stp/
TRY :: for l in ruby perl;do $l -e “print “\x3a\x2d\x29\x0a””;done
===============================================================================


(Ara.T.Howard) #4

this version is even more informative…

~ > cat int_max.rb

require 'tmpdir’
require ‘ftools’

c_prog = <<-code
#include <limits.h>
main(){int i = INT_MAX; write(1,&i,sizeof(int));}
code

tmp = Dir::tmpdir

a_c = File.join tmp, 'a.c’
a_out = File.join tmp, 'a.out’
out = File.join tmp, ‘out’

open(a_c, ‘w’){|f| f.write c_prog}
system "cc #{ a_c } -o #{ a_out }"
system “#{ a_out } > #{ out }”

int_max = IO.read(out).unpack(‘i’).first

p(int_max)
p((2 ** 31) - 1)
p("%032.32b" % int_max)

p(0xFFFFFFFF)
p((2 ** 32) - 1)
p("%032.32b" % 0xFFFFFFFF)

File.rm_f a_c
File.rm_f a_out
File.rm_f out

-a

···

On Wed, 18 Feb 2004, Ara.T.Howard wrote:

EMAIL :: Ara [dot] T [dot] Howard [at] noaa [dot] gov
PHONE :: 303.497.6469
ADDRESS :: E/GC2 325 Broadway, Boulder, CO 80305-3328
URL :: http://www.ngdc.noaa.gov/stp/
TRY :: for l in ruby perl;do $l -e “print “\x3a\x2d\x29\x0a””;done
===============================================================================