Hi,

So, I came up with a solution, and would be grateful for Ruby style  
tips. It seemed a lot harder to do than it needed to be.

Any help appreciated.

Thanks,
Bob

The Tests:

class ByteReaderTest < Test::Unit::TestCase

   def test_read_signed4_negative
     negative = "" << 0xF2 << 0x34 << 0x56 << 0x78
     assert_equal -231451016, signed4(StringIO.new(negative))
   end

   def test_read_signed4_positive
     positive = "" << 0x02 << 0x34 << 0x56 << 0x78
     assert_equal 36984440, signed4(StringIO.new(positive))
   end

end

The Solution:

def signed4(file)
   bits = (file.read(4).unpack('B32'))[0]
   if bits[0..0].eql? "0" # sign bit is positive
     bits.to_i(2)
   else # sign bit is negative
     compute_negative_number_from(bits)
   end
end

def compute_negative_number_from(bits)
   twos_complement = flip(bits).join.to_i(2) + 1
   -1 * twos_complement
end

def flip(bits)
   bits.scan(/\w/).collect { |bit| (bit.eql?("1")) ? "0" : "1" }
end


On Nov 14, 2005, at 3:07 PM, 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
>