From: Robert Evans Date: 2005-11-16T03:37:25+09:00 Subject: Re: Solution Comments on Re: Reading a signed byte in network byte order Sweet. That's a very slick answer. Thanks. Bob On Nov 15, 2005, at 9:56 AM, Ara.T.Howard wrote: > On Wed, 16 Nov 2005, Robert Evans 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 > > harp:~ > cat a.rb > require "test/unit" > class ByteReaderTest < Test::Unit::TestCase > MAX_POS = 2 ** 31 -1 > BIG_ENDIAN = [42].pack('N') == [42].pack('i') > def test_read_signed4_positive > positive = [0x02, 0x34, 0x56, 0x78].pack "c*" > assert_equal 36984440, signed4(positive) > end > def test_read_signed4_negative > negative = [0xF2, 0x34, 0x56, 0x78].pack "c*" > assert_equal -231451016, signed4(negative) > end > def signed4 buf > buf = buf.read 4 if buf.respond_to? "read" > raise RangeError unless buf.size == 4 > n = buf.unpack('N').first > if n > MAX_POS > (BIG_ENDIAN ? buf : buf.reverse).unpack('l').first > else > n > end > end > end > > > harp:~ > ruby a.rb > Loaded suite a > Started > .. > Finished in 0.000583 seconds. > > 2 tests, 2 assertions, 0 failures, 0 errors > > > -a > -- > ====================================================================== > ========= > | ara [dot] t [dot] howard [at] gmail [dot] com > | all happiness comes from the desire for others to be happy. all > misery > | comes from the desire for oneself to be happy. > | -- bodhicaryavatara > ====================================================================== > ========= > >