Binary numbers

K

Kim Pedersen

Hi,

I have some data with binary numbers.
e.g. a 3 byte string could be 0x01216f which is 74095 decimal.
To do this conversion in ruby I've come up with:

def binum(bs)
n = e = 0
bs.reverse.each_byte do |c|
n += c * 256 ** e
e += 1
end
n
end

bs = ''
bs << 0x01 << 0x21 << 0x6f

puts binum(bs) => 74095

Now some data are signed binary numbers stored as two's complement.
e.g. 0xfede91 which is -74095 decimal.

How can I do this conversion in ruby?

Best regards,
Kim
 
D

Dale Martenson

Hi,

I have some data with binary numbers.
e.g. a 3 byte string could be 0x01216f which is 74095 decimal.
To do this conversion in ruby I've come up with:

def binum(bs)
n = e = 0
bs.reverse.each_byte do |c|
n += c * 256 ** e
e += 1
end
n
end

bs = ''
bs << 0x01 << 0x21 << 0x6f

puts binum(bs) => 74095

Now some data are signed binary numbers stored as two's complement.
e.g. 0xfede91 which is -74095 decimal.

How can I do this conversion in ruby?

def binum(bs)
result = 0
bs.unpack("cCC").each {|b| result = (result << 8) | b }
result
end

bs = ''
bs << 0x01 << 0x21 << 0x6f

puts binum(bs)

bs = ''
bs << 0xfe << 0xde << 0x91

puts binum(bs)

The above code extracts the first byte as a signed 8-bit integer and the
rest of the bytes as unsigned 8-bit integers. Each iteration through the
loop shift the result to construct the proper value.

--Dale Martenson
 
J

James Edward Gray II

def binum(bs)
result = 0
bs.unpack("cCC").each {|b| result = (result << 8) | b }
result
end

That's just crying out for inject():

bs.unpack("cCC").inject(0) { |res, b| (res << 8) | b }

;)

James Edward Gray II
 
K

Kim Pedersen

Dale said:
def binum(bs)
result = 0
bs.unpack("cCC").each {|b| result = (result << 8) | b }
result
end

bs = ''
bs << 0x01 << 0x21 << 0x6f

puts binum(bs)

bs = ''
bs << 0xfe << 0xde << 0x91

puts binum(bs)

The above code extracts the first byte as a signed 8-bit integer and the
rest of the bytes as unsigned 8-bit integers. Each iteration through the
loop shift the result to construct the proper value.

--Dale Martenson
Great!
Thanks
Kim

BTW, the length of the string may vary from 1 to 8. I'll have to adjust
for that.
 
K

Kim Pedersen

James said:
That's just crying out for inject():

bs.unpack("cCC").inject(0) { |res, b| (res << 8) | b }

;)

James Edward Gray II
Thanks,
ps. just bought your ruby quiz book :)
 
D

David Balmain

Great!
Thanks
Kim

BTW, the length of the string may vary from 1 to 8. I'll have to adjust
for that.

For variable length;

c.unpack("cC*").inject(0) { |res, b| (res << 8) | b }
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,480
Members
44,900
Latest member
Nell636132

Latest Threads

Top