Is there a way to pack() a signed long in a portable fashion (i.e. it
should work on both little endian and big endian machines)?
The pack() function has these options:
‘l’ => { :signed => true, :network => false }
‘N’ => { :signed => false, :network => true }
But I cannot find an option that is { :signed => true, :network => true }!
So if I pack with ‘l’, it won’t work on different architectures. And
if I pack with ‘N’, it won’t allow negative numbers.
For now, I think I have to pack with ‘N’, but add 232 before packing
and subtract 232 after unpacking, but I think there ought to be a
better way?
Philip Mak wrote:
Is there a way to pack() a signed long in a portable fashion (i.e. it
should work on both little endian and big endian machines)?
The pack() function has these options:
‘l’ => { :signed => true, :network => false }
‘N’ => { :signed => false, :network => true }
But I cannot find an option that is { :signed => true, :network => true }!
So if I pack with ‘l’, it won’t work on different architectures. And
if I pack with ‘N’, it won’t allow negative numbers.
For now, I think I have to pack with ‘N’, but add 232 before packing
and subtract 232 after unpacking, but I think there ought to be a
better way?
Will this do?
if [1].pack(“N”) == [1].pack(“I”) # big endian
array.pack(“l*”).reverse
else
array.pack(“l*”)
end
Regards,
Dan
···
–
a = [74, 117, 115, 116, 32, 65, 110, 111, 116, 104, 101, 114, 32, 82]
a.push(117,98, 121, 32, 72, 97, 99, 107, 101, 114)
puts a.pack(“C*”)
Won’t this transform the number into a Bignum?
Believe it’s 2**31 (remember Fixnum’s length), but am not really sure…
···
On Wed, Apr 09, 2003 at 05:46:03AM +0900, Philip Mak wrote:
Is there a way to pack() a signed long in a portable fashion (i.e. it
should work on both little endian and big endian machines)?
The pack() function has these options:
‘l’ => { :signed => true, :network => false }
‘N’ => { :signed => false, :network => true }
But I cannot find an option that is { :signed => true, :network => true }!
So if I pack with ‘l’, it won’t work on different architectures. And
if I pack with ‘N’, it won’t allow negative numbers.
For now, I think I have to pack with ‘N’, but add 232 before packing
and subtract 232 after unpacking, but I think there ought to be a
better way?
–
_ _
__ __ | | ___ _ __ ___ __ _ _ __
'_ \ / | __/ __| '_
_ \ / ` | ’ \
) | (| | |__ \ | | | | | (| | | | |
.__/ _,|_|/| || ||_,|| |_|
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com
lp1 on fire
– One of the more obfuscated kernel messages
[-1].pack(“N”)
=> “\377\377\377\377”
Looks OK to me for packing. Unpacking treats this as unsigned though; you
could just test for values >= 231 and subtract 232
···
On Wed, Apr 09, 2003 at 05:46:03AM +0900, Philip Mak wrote:
So if I pack with ‘l’, it won’t work on different architectures. And
if I pack with ‘N’, it won’t allow negative numbers.
Why not pack it as:
m = -1 # => -1
n = [m < 0 ? 1 : 0, m.abs].pack(“N*”)
# => “\001\000\000\000\001\000\000\000”
o = n.unpack(“N*”)
p = o[1] * (o[0] ? -1 : 1)
Yes, it means you have to know the encoding on both sides, but it
seems less risky than adding 2**32.
-austin
– Austin Ziegler, austin@halostatue.ca on 2003.04.08 at 22:45:34
···
On Wed, 9 Apr 2003 05:46:03 +0900, Philip Mak wrote:
Is there a way to pack() a signed long in a portable fashion (i.e.
it should work on both little endian and big endian machines)?
The pack() function has these options:
‘l’ => { :signed => true, :network => false }
‘N’ => { :signed => false, :network => true }
But I cannot find an option that is { :signed => true, :network =>
true }!
So if I pack with ‘l’, it won’t work on different architectures.
And if I pack with ‘N’, it won’t allow negative numbers.
For now, I think I have to pack with ‘N’, but add 232 before
packing and subtract 232 after unpacking, but I think there
ought to be a better way?