Hi Robert,

I'm probably missing something here, but how about this? It works for
your tests at least.

def signed4(file)
  file.read(4).reverse.unpack('l')[0]
end

Cheers,
Dave

On 11/16/05, Robert Evans <robert.evans / acm.org> wrote:
> 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
> >
>
>
>