From: Austin Ziegler Date: 2007-02-15T07:13:40+09:00 Subject: Re: Converting Bytes to a Negative Integer On 2/14/07, James Edward Gray II wrote: > On Feb 14, 2007, at 2:27 PM, Harris Reynolds wrote: > > 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 = [x].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 = [x].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 -- Austin Ziegler * halostatue@gmail.com * http://www.halostatue.ca/ * austin@halostatue.ca * http://www.halostatue.ca/feed/ * austin@zieglers.ca