Forum: Ruby pack("l"), 64 bit question

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
F3b7b8756d0c7f71cc7460cc33aefaee?d=identicon&s=25 Daniel Berger (Guest)
on 2006-02-15 17:52
(Received via mailing list)
Hi all,

Ruby 1.8.4
Solaris 10

Is this correct?

# 32 bit
irb(main):002:0> [-1].pack("l")
=> "\377\377\377\377"
irb(main):003:0> "\377\377\377\377".unpack("l")
=> [-1]

# 64 bit
irb(main):002:0> [-1].pack("l")
=> "\377\377\377\377"
irb(main):003:0> "\377\377\377\377".unpack("l")
=> [4294967295]

Regards,

Dan
Cb48ca5059faf7409a5ab3745a964696?d=identicon&s=25 unknown (Guest)
on 2006-02-15 17:55
(Received via mailing list)
On Thu, 16 Feb 2006, Daniel Berger wrote:

> irb(main):003:0> "\377\377\377\377".unpack("l")
> Dan
yes.  'l' is unsigned.  i think you may want 'i'.

regards.

-a
Cb48ca5059faf7409a5ab3745a964696?d=identicon&s=25 unknown (Guest)
on 2006-02-15 18:04
(Received via mailing list)
On Thu, 16 Feb 2006, Daniel Berger wrote:

> irb(main):003:0> "\377\377\377\377".unpack("l")
> Dan
btw.  this is useful for me

   irb(main):008:0> to_bin = lambda{|s| '[ ' << s.unpack('c*').map{|b|
'%8.8b' % b}.join(' ') << ' ]'}
   => #<Proc:0xb7569f90@(irb):8>

   irb(main):009:0> to_bin[ [-1].pack("l") ]
   => "[ 11111111 11111111 11111111 11111111 ]"

   irb(main):010:0> to_bin[ [-1].pack("i") ]
   => "[ 11111111 11111111 11111111 11111111 ]"

   irb(main):011:0> to_bin[ [1].pack("l") ]
   => "[ 00000001 00000000 00000000 00000000 ]"

   irb(main):012:0> to_bin[ [1].pack("i") ]
   => "[ 00000001 00000000 00000000 00000000 ]"


-a
0ec4920185b657a03edf01fff96b4e9b?d=identicon&s=25 Yukihiro Matsumoto (Guest)
on 2006-02-15 18:38
(Received via mailing list)
Hi,

In message "Re: pack("l"), 64 bit question"
    on Thu, 16 Feb 2006 01:50:34 +0900, Daniel Berger
<Daniel.Berger@qwest.com> writes:

|Ruby 1.8.4
|Solaris 10
|
|Is this correct?
|
|# 32 bit
|irb(main):002:0> [-1].pack("l")
|=> "\377\377\377\377"
|irb(main):003:0> "\377\377\377\377".unpack("l")
|=> [-1]
|
|# 64 bit
|irb(main):002:0> [-1].pack("l")
|=> "\377\377\377\377"
|irb(main):003:0> "\377\377\377\377".unpack("l")
|=> [4294967295]

Hmm, unpack("l") should have returned negative value unless "_" suffix
is supplied.

							matz.
F3b7b8756d0c7f71cc7460cc33aefaee?d=identicon&s=25 Daniel Berger (Guest)
on 2006-02-15 18:50
(Received via mailing list)
Yukihiro Matsumoto wrote:
> |Is this correct?
> |irb(main):003:0> "\377\377\377\377".unpack("l")
> |=> [4294967295]
>
> Hmm, unpack("l") should have returned negative value unless "_" suffix
> is supplied.
>
> 							matz.
>

Here's some more info that may or may not be useful:

# 64 bit
irb(main):004:0> "\377\377\377\377".unpack("l_")
=> [nil]
irb(main):005:0> [-1].pack("l_")
=> "\377\377\377\377\377\377\377\377"
irb(main):006:0> "\377\377\377\377\377\377\377\377".unpack("l_")
=> [-1]

Regards,

Dan
0ec4920185b657a03edf01fff96b4e9b?d=identicon&s=25 Yukihiro Matsumoto (Guest)
on 2006-02-15 18:50
(Received via mailing list)
Hi,

In message "Re: pack("l"), 64 bit question"
    on Thu, 16 Feb 2006 02:35:53 +0900, Yukihiro Matsumoto
<matz@ruby-lang.org> writes:

||irb(main):003:0> "\377\377\377\377".unpack("l")
||=> [4294967295]
|
|Hmm, unpack("l") should have returned negative value unless "_" suffix
|is supplied.

This means EXTEND32() macro in pack.c is not working on 64bit Solaris
(and perhaps on other 64bit systems neither).  I have no 64bit machine
at hand.  Could somebody confirm?

							matz.
A60a5ad91da9053cd6402042f433ee67?d=identicon&s=25 H.Yamamoto (Guest)
on 2006-02-16 09:46
(Received via mailing list)
Hello.

>This means EXTEND32() macro in pack.c is not working on 64bit Solaris
>(and perhaps on other 64bit systems neither).  I have no 64bit machine
>at hand.  Could somebody confirm?

Me neigher. But we can use HP TestDrive :-)

Probably this patch will solve the problem.

Index: pack.c
===================================================================
RCS file: /src/ruby/pack.c,v
retrieving revision 1.62.2.12
diff -u -w -b -p -r1.62.2.12 pack.c
--- pack.c	13 Oct 2005 14:30:49 -0000	1.62.2.12
+++ pack.c	16 Feb 2006 06:01:07 -0000
@@ -347,11 +347,11 @@ num2i32(x)
     return 0;			/* not reached */
 }

-#if SIZEOF_LONG == SIZE32 || SIZEOF_INT == SIZE32
+#if SIZEOF_LONG == SIZE32
 # define EXTEND32(x)
 #else
 /* invariant in modulo 1<<31 */
-# define EXTEND32(x) do {if (!natint) {(x) =
(I32)(((1<<31)-1-(x))^~(~0<<31));}} while(0)
+# define EXTEND32(x) do { if (!natint) {(x) =
(((1L<<31)-1-(x))^~(~0L<<31));}} while(0)
 #endif
 #if SIZEOF_SHORT == SIZE16
 # define EXTEND16(x)
0ec4920185b657a03edf01fff96b4e9b?d=identicon&s=25 Yukihiro Matsumoto (Guest)
on 2006-02-16 09:52
(Received via mailing list)
Hi,

In message "Re: pack("l"), 64 bit question"
    on Thu, 16 Feb 2006 17:45:50 +0900, H.Yamamoto
<ocean@m2.ccsnet.ne.jp> writes:
|
|>This means EXTEND32() macro in pack.c is not working on 64bit Solaris
|>(and perhaps on other 64bit systems neither).  I have no 64bit machine
|>at hand.  Could somebody confirm?
|
|Me neigher. But we can use HP TestDrive :-)
|
|Probably this patch will solve the problem.

Daniel, could you try this patch on your 64bit box?

							matz.

|--- pack.c	13 Oct 2005 14:30:49 -0000	1.62.2.12
|+++ pack.c	16 Feb 2006 06:01:07 -0000
|@@ -347,11 +347,11 @@ num2i32(x)
|     return 0;			/* not reached */
| }
|
|-#if SIZEOF_LONG == SIZE32 || SIZEOF_INT == SIZE32
|+#if SIZEOF_LONG == SIZE32
| # define EXTEND32(x)
| #else
| /* invariant in modulo 1<<31 */
|-# define EXTEND32(x) do {if (!natint) {(x) = (I32)(((1<<31)-1-(x))^~(~0<<31));}} 
while(0)
|+# define EXTEND32(x) do { if (!natint) {(x) = (((1L<<31)-1-(x))^~(~0L<<31));}} while(0)
| #endif
| #if SIZEOF_SHORT == SIZE16
| # define EXTEND16(x)
0e303bc908294a8870899b77338ba807?d=identicon&s=25 Ville Mattila (Guest)
on 2006-02-16 11:11
(Received via mailing list)
Yukihiro Matsumoto <matz@ruby-lang.org> writes:

> |
> |Probably this patch will solve the problem.
>
> Daniel, could you try this patch on your 64bit box?

  The pach works for me on my opteron 64 box. Here is another.
  The sun studio cc, warned
cc: Warning: -fsimple option is ignored.
"../pack.c", line 1954: warning: integer overflow detected: op "<<"
"../pack.c", line 1954: warning: initializer does not fit or is out of
range: -144115188075855872

   Is the patch correct?

index: pack.c
===================================================================
RCS file: /src/ruby/pack.c,v
retrieving revision 1.62.2.12
@@ -1951,7 +1951,7 @@ pack_unpack(str, fmt)
          case 'w':
            {
                unsigned long ul = 0;
-               unsigned long ulmask = 0xfeL << ((sizeof(unsigned long)
- 1) * 8);
+               unsigned long ulmask = 0xfeUL << ((sizeof(unsigned long)
- 1UL) * 8UL);

                while (len > 0 && s < send) {
                    ul <<= 7;
F3b7b8756d0c7f71cc7460cc33aefaee?d=identicon&s=25 Daniel Berger (Guest)
on 2006-02-16 17:50
(Received via mailing list)
Yukihiro Matsumoto wrote:
> |
> | }
> | # define EXTEND16(x)
>

Looks good.  The only one I found odd was the [nil] returned by
"\377\377\377\377".unpack("l_").  Is that expected?  The 32 bit version
returns
[-1].

# 64 bit Ruby

irb(main):001:0> [-1].pack("l")
=> "\377\377\377\377"
irb(main):002:0> "\377\377\377\377".unpack("l")
=> [-1]
irb(main):003:0> "\377\377\377\377".unpack("l_")
=> [nil]
irb(main):004:0> [-1].pack("l_")
=> "\377\377\377\377\377\377\377\377"
irb(main):005:0> "\377\377\377\377\377\377\377\377".unpack("l")
=> [-1]
irb(main):006:0> "\377\377\377\377\377\377\377\377".unpack("l_")
=> [-1]

Thanks,

Dan
0ec4920185b657a03edf01fff96b4e9b?d=identicon&s=25 Yukihiro Matsumoto (Guest)
on 2006-02-16 23:50
(Received via mailing list)
Hi,

In message "Re: pack("l"), 64 bit question"
    on Fri, 17 Feb 2006 01:47:36 +0900, Daniel Berger
<Daniel.Berger@qwest.com> writes:

|> Daniel, could you try this patch on your 64bit box?

|Looks good.  The only one I found odd was the [nil] returned by
|"\377\377\377\377".unpack("l_").  Is that expected?  The 32 bit version returns
|[-1].

No, it should return [4294967295].  How about a patch from Ville
Mattila in [ruby-talk:180126]?

							matz.
A60a5ad91da9053cd6402042f433ee67?d=identicon&s=25 H.Yamamoto (Guest)
on 2006-02-17 01:48
(Received via mailing list)
Hello.

>|Looks good.  The only one I found odd was the [nil] returned by
>|"\377\377\377\377".unpack("l_").  Is that expected?  The 32 bit version returns
>|[-1].
>
>No, it should return [4294967295].  How about a patch from Ville
>Mattila in [ruby-talk:180126]?

Are these also unexpected?

irb(main):009:0> [123].pack("s").unpack("l")
=> [nil]
irb(main):010:0> [123].pack("s").unpack("q")
=> [nil]
irb(main):011:0> [123].pack("l").unpack("q")
=> [nil]
0ec4920185b657a03edf01fff96b4e9b?d=identicon&s=25 Yukihiro Matsumoto (Guest)
on 2006-02-17 03:16
(Received via mailing list)
Hi,

In message "Re: pack("l"), 64 bit question"
    on Fri, 17 Feb 2006 09:46:25 +0900, H.Yamamoto
<ocean@m2.ccsnet.ne.jp> writes:

|Are these also unexpected?
|
|irb(main):009:0> [123].pack("s").unpack("l")
|=> [nil]
|irb(main):010:0> [123].pack("s").unpack("q")
|=> [nil]
|irb(main):011:0> [123].pack("l").unpack("q")
|=> [nil]

Wait, ... I see.  "\377\377\377\377".unpack("l_") gives you nil
because it's shorter than sizeof(long) on the platform.  So they are
all OK.  Thank you.

Ocean, could you commit your patch?

							matz.
This topic is locked and can not be replied to.