Converting Bytes to a Negative Integer

I really like the to_signed proc idea at the bottom of this message... the procedure doesn't work however in all cases... note the Ruby code below:

bits = 32
max_unsigned = 2 ** bits
max_signed = 2 ** (bits - 1)
to_signed = proc { |n| (n >= max_signed) ? n - max_unsigned : n }

x = -123
s = .pack("N")
puts to_signed[s.unpack("N").first]

y = 7777777
s = [y].pack("N")
puts to_signed[s.unpack("N").first]

# try converting 7777777 when you already have the bytes
z = ""
[129, 237, 173, 241].each { |e| z << e }
puts to_signed[z.unpack("N").first]

# OUTPUT

ruby signed_test.rb

-123
7777777
-2115129871

Coverting the bytes of 7777777 yields a pretty nasty negative number in this case.

~harris

> Let's say I have 4 bytes:
>
> 255 255 255 236

>> bytes = [255, 255, 255, 236].map { |b| b.chr }.join
=> "\377\377\377\354"

> The binary representation of this is:
>
> 11111111
> 11111111
> 11111111
> 11101100

>> bytes.unpack("B*").first.scan(/[01]{8}/)
=> ["11111111", "11111111", "11111111", "11101100"]

> The decimal number should be -20. Does anyone know how to convert
> these 4 bytes into an Integer?

This is where I had trouble. I found the following:

>> bytes.reverse.unpack("l*").first
=> -20

This is tied to my processor though. I had to reverse the bytes
because they are not in the order my machine expects.

unpack() has directives for when the order is known, but all of those
seemed to be unsigned.

I'm anxious to see the cross-platform solution for this...

Joel VanDerWerf had something that I'll be adapting if I need it elsewhere.

x = -123
s = .pack("N")

bits = 32
max_unsigned = 2 ** bits
max_signed = 2 ** (bits - 1)
to_signed = proc { |n| (n >= max_signed) ? n - max_unsigned : n }

puts to_signed[s.unpack("N").first]

I need it for unsigned->signed words, so:

x = -123
s = .pack("n")

bits = 16
max_unsigned = 2 ** bits
max_signed = 2 ** (bits - 1)
to_signed = proc { |n| (n >= max_signed) ? n - max_unsigned : n }

puts to_signed[s.unpack("n").first]

-austin

···

On 2/14/07, James Edward Gray II <james / grayproductions.net> wrote:

On Feb 14, 2007, at 2:27 PM, Harris Reynolds wrote:

--
Austin Ziegler * halostatue@gmail.com * http://www.halostatue.ca/
* austin@halostatue.ca * You are in a maze of twisty little passages, all alike. // halo • statue
* austin@zieglers.ca

____________________________________________________________________________________
Cheap talk?
Check out Yahoo! Messenger's low PC-to-Phone call rates.
http://voice.yahoo.com

____________________________________________________________________________________
Food fight? Enjoy some healthy debate
in the Yahoo! Answers Food & Drink Q&A.
http://answers.yahoo.com/dir/?link=list&sid=396545367

The bytes are wrong. The bytes for 7,777,777 in "N" format are [0,
118, 173, 241].

-austin

···

On 2/15/07, Harris Reynolds <hreynolds2@yahoo.com> wrote:

# try converting 7777777 when you already have the bytes
z = ""
[129, 237, 173, 241].each { |e| z << e }
puts to_signed[z.unpack("N").first]

--
Austin Ziegler * halostatue@gmail.com * http://www.halostatue.ca/
               * austin@halostatue.ca * You are in a maze of twisty little passages, all alike. // halo • statue
               * austin@zieglers.ca