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__
···
----------------------------------------
#<C foo=-12345678, bar=12345678>
----------------------------------------
"\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