From: Joel VanderWerf Date: 2005-11-16T08:10:19+09:00 Subject: Re: Reading a signed byte in network byte order Robert Evans wrote: > Hi, > > In trying to read 4 bytes as a signed integer from an IO in big- endian > order, is there already a utility to do this in Ruby? I notice unpack > has lots of combinations already, but seemingly not one for this. Maybe > I am just missing it? > > Thanks, > Bob Evans You can unpack with "N" and then use the following to interpret that positive Integer as a signed number in 32 bit two's complement representation and convert it to a positive or negative Integer: length = 32 # bits max = 2**length-1 mid = 2**(length-1) to_signed = proc {|n| (n>=mid) ? -((n ^ max) + 1) : n} For example: irb(main):012:0> to_signed[4294967295] => -1 This is a snippet from the implementation of my bit-struct lib (see RAA). A BitStruct is basically a string with some extra accessors and convenience methods. Currently it handles fields that are either multiple bytes or 1-7 bits within a byte. (Eventually, longer odd-size bit fields would be nice.) Also supports fields for: fixed length char strings, null-terminated strings, hex octets, decimal octets, floats, nested BitStructs, and "rest"--the rest of the string after defined fields. It's *really* useful for playing with net protocols in pure ruby. (Someday, I'll probably write a C extension for efficiency.) Example: require 'bit-struct' class C < BitStruct signed :foo, 32, "Something signed" unsigned :bar, 32, "Something UNsigned" end c = C.new c.foo = -12345678 c.bar = 12345678 puts "-"*40 p c puts "-"*40 p c.to_s puts "-"*40 puts c.inspect_detailed puts "-"*40 p c.to_h puts "-"*40 puts C.describe __END__ ---------------------------------------- # ---------------------------------------- "\377C\236\262\000\274aN" ---------------------------------------- C: Something signed = -12345678 Something UNsigned = 12345678 ---------------------------------------- {:bar=>12345678, :foo=>-12345678} ---------------------------------------- byte: type name [size] description ---------------------------------------------------------------------- @0: signed foo [ 32b] Something signed @4: unsigned bar [ 32b] Something UNsigned -- vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407