Using Ruby/DL, it seems as though a 32-bit integer with the MSB set cannot be converted to a long integer:
require 'dl'
DL::dlopen("libc.so.5") do |libc|
isdigit = libc['isdigit', 'CH']
p 0x40000000.class
print(isdigit.call(0x40000000), "\n")
p 0x80000000.class
print(isdigit.call(0x80000000), "\n")
end
The above will print the first one successfully, even though 0x40000000 is a Bignum. The second one results in an error:
in `call': bignum too big to convert into `long' (RangeError)
Is this a bug, or a feature? Is there a workaround? Any advice would be appreciated.
Thanks,
Jamis
···
--
Jamis Buck
jgb3@email.byu.edu
http://www.jamisbuck.org/jamis
I think the call is failing because of some code in bignum.c:
lines 765-776:
long
rb_big2long(x)
VALUE x;
{
unsigned long num = big2ulong(x, "long");
if ((long)num < 0 && (RBIGNUM(x)->sign || (long)num != LONG_MIN)) {
rb_raise(rb_eRangeError, "bignum too big to convert into `long'");
}
if (!RBIGNUM(x)->sign) return -(long)num;
return num;
}
It checks to see if the number goes negative when trying to convert it
to a long, and if so, raises an exception. In this case you are using
a hex value to set an integer that you intend to be negative, but Ruby
treats this as a positive integer. Perhaps you could get around it by
putting the number in as a negative:
#!/usr/bin/env ruby
require 'dl'
DL::dlopen("libc.dylib") do |libc|
isdigit = libc['isdigit', 'CH']
p 0x40000000.class
print(isdigit.call(0x40000000), "\n")
p -2147483648.class
print(isdigit.call(-2147483648), "\n")
end
Here is the output:
Bignum
01073741824
Bignum
0-2147483648
···
On Sat, 23 Oct 2004 13:23:22 +0900, Jamis Buck <jgb3@email.byu.edu> wrote:
Using Ruby/DL, it seems as though a 32-bit integer with the MSB set
cannot be converted to a long integer:
require 'dl'
DL::dlopen("libc.so.5") do |libc|
isdigit = libc['isdigit', 'CH']
p 0x40000000.class
print(isdigit.call(0x40000000), "\n")
p 0x80000000.class
print(isdigit.call(0x80000000), "\n")
end
The above will print the first one successfully, even though 0x40000000
is a Bignum. The second one results in an error:
in `call': bignum too big to convert into `long' (RangeError)
Is this a bug, or a feature? Is there a workaround? Any advice would be
appreciated.
Thanks,
Jamis
--
Jamis Buck
jgb3@email.byu.edu
http://www.jamisbuck.org/jamis