[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.ruby

Re: pack bug on 64-bit ruby

Berger, Daniel

11/17/2003 10:04:00 PM

> -----Original Message-----
> From: Lyle Johnson [mailto:lyle@users.sourceforge.net]
> Sent: Monday, November 17, 2003 2:47 PM
> To: ruby-talk ML
> Subject: Re: pack bug on 64-bit ruby
>
>
> Daniel Berger wrote:
>
> > Looks like there's a 64-bit related bug in pack():
> >
> > irb(main):007:0> [-1].pack("V")
> > RangeError: integer 18446744073709551615 too big to convert to
> > `unsigned int'
> > from (irb):7:in `pack'
> > from (irb):7
>
> If Array#pack is supposed to output a four-character string for the
> *unsigned* long value, I think maybe this shouldn't work for 64-bit.
> You're passing in a value of -1, which is 2**64 - 1 when
> represented as
> an unsigned long on a 64-bit machine. You can't pack that into four
> characters (bytes).
>
> Out of curiosity, what happens if you instead try this?
>
> [-1].pack("L_")
>
> Note the trailing underscore. If I read the code right, this
> should do
> the right thing.

Thanks Lyle - that seems to work although (as expected I think) it does
it in 8 bytes.

The question I have now then is, if I've got code that uses
[-1].pack("V"), how should I handle this on 64 bit platforms? Is there
a way to tell the bit-ness of Ruby from within Ruby? Perhaps a
RUBY_BITNESS constant? Or is there some sort of "cross-bitness"
approach I can use?

Regards,

Dan

3 Answers

nobu.nokada

11/18/2003 12:51:00 AM

0

Hi,

At Tue, 18 Nov 2003 07:03:54 +0900,
Berger, Daniel wrote:
> The question I have now then is, if I've got code that uses
> [-1].pack("V"), how should I handle this on 64 bit platforms? Is there
> a way to tell the bit-ness of Ruby from within Ruby? Perhaps a
> RUBY_BITNESS constant? Or is there some sort of "cross-bitness"
> approach I can use?

[-1].pack("v") gently gives "\377\377" on 32 bit platforms, so
it might be better to just mask, like as Perl.


* pack.c (pack_pack): mask for lower bits. [ruby-talk:85377]

Index: pack.c
===================================================================
RCS file: /cvs/ruby/src/ruby/pack.c,v
retrieving revision 1.57
diff -u -2 -p -r1.57 pack.c
--- pack.c 9 Oct 2003 17:45:52 -0000 1.57
+++ pack.c 18 Nov 2003 00:45:32 -0000
@@ -676,4 +676,5 @@ pack_pack(ary, fmt)
if (NIL_P(from)) s = 0;
else {
+ from = rb_funcall(from, '&', 1, INT2FIX(0xffff));
s = NUM2INT(from);
}
@@ -690,5 +691,6 @@ pack_pack(ary, fmt)
if (NIL_P(from)) l = 0;
else {
- l = NATINT_U32(from);
+ from = rb_funcall(from, '&', 1, UINT2NUM(0xffffffff));
+ l = NUM2ULONG(from);
}
l = htonl(l);
@@ -704,4 +706,5 @@ pack_pack(ary, fmt)
if (NIL_P(from)) s = 0;
else {
+ from = rb_funcall(from, '&', 1, INT2FIX(0xffff));
s = NUM2INT(from);
}
@@ -718,5 +721,6 @@ pack_pack(ary, fmt)
if (NIL_P(from)) l = 0;
else {
- l = NATINT_U32(from);
+ from = rb_funcall(from, '&', 1, UINT2NUM(0xffffffff));
+ l = NUM2ULONG(from);
}
l = htovl(l);


--
Nobu Nakada


Berger, Daniel

11/19/2003 3:25:00 PM

0

nobu.nokada@softhome.net wrote:
>
> Hi,
>
> At Tue, 18 Nov 2003 07:03:54 +0900,
> Berger, Daniel wrote:
> > The question I have now then is, if I've got code that uses
> > [-1].pack("V"), how should I handle this on 64 bit platforms? Is there
> > a way to tell the bit-ness of Ruby from within Ruby? Perhaps a
> > RUBY_BITNESS constant? Or is there some sort of "cross-bitness"
> > approach I can use?
>
> [-1].pack("v") gently gives "\377\377" on 32 bit platforms, so
> it might be better to just mask, like as Perl.
>
> * pack.c (pack_pack): mask for lower bits. [ruby-talk:85377]
>
> Index: pack.c
> ===================================================================
> RCS file: /cvs/ruby/src/ruby/pack.c,v
> retrieving revision 1.57
> diff -u -2 -p -r1.57 pack.c
> --- pack.c 9 Oct 2003 17:45:52 -0000 1.57
> +++ pack.c 18 Nov 2003 00:45:32 -0000
> @@ -676,4 +676,5 @@ pack_pack(ary, fmt)
> if (NIL_P(from)) s = 0;
> else {
> + from = rb_funcall(from, '&', 1, INT2FIX(0xffff));
> s = NUM2INT(from);
> }
> @@ -690,5 +691,6 @@ pack_pack(ary, fmt)
> if (NIL_P(from)) l = 0;
> else {
> - l = NATINT_U32(from);
> + from = rb_funcall(from, '&', 1, UINT2NUM(0xffffffff));
> + l = NUM2ULONG(from);
> }
> l = htonl(l);
> @@ -704,4 +706,5 @@ pack_pack(ary, fmt)
> if (NIL_P(from)) s = 0;
> else {
> + from = rb_funcall(from, '&', 1, INT2FIX(0xffff));
> s = NUM2INT(from);
> }
> @@ -718,5 +721,6 @@ pack_pack(ary, fmt)
> if (NIL_P(from)) l = 0;
> else {
> - l = NATINT_U32(from);
> + from = rb_funcall(from, '&', 1, UINT2NUM(0xffffffff));
> + l = NUM2ULONG(from);
> }
> l = htovl(l);
>
> --
> Nobu Nakada

Forgive my ignorance, but does this just mean that pack("V") is always
32 bits, as in Perl?

Dan


nobu.nokada

11/27/2003 3:37:00 AM

0

Hi,

At Thu, 20 Nov 2003 00:25:03 +0900,
Daniel Berger wrote:
> Forgive my ignorance, but does this just mean that pack("V") is always
> 32 bits, as in Perl?

Yes, masking except lower bits.

--
Nobu Nakada