[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Ruby/DL: bignum->long

Jamis Buck

10/23/2004 4:23:00 AM

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


1 Answer

Carl Youngblood

10/23/2004 3:18:00 PM

0

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