Velocity Reviews > Ruby > Binary numbers

# Binary numbers

Kim Pedersen
Guest
Posts: n/a

 08-01-2006
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

Dale Martenson
Guest
Posts: n/a

 08-01-2006

On Wednesday, August 02, 2006, at 5:46 AM, Kim Pedersen wrote:
>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 << | 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

--

James Edward Gray II
Guest
Posts: n/a

 08-01-2006
On Aug 1, 2006, at 4:33 PM, Dale Martenson wrote:

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

That's just crying out for inject():

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

James Edward Gray II

Kim Pedersen
Guest
Posts: n/a

 08-01-2006
Dale Martenson wrote:
> On Wednesday, August 02, 2006, at 5:46 AM, Kim Pedersen wrote:
>
>> 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 << | 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.

Kim Pedersen
Guest
Posts: n/a

 08-01-2006
James Edward Gray II wrote:
> On Aug 1, 2006, at 4:33 PM, Dale Martenson wrote:
>
>> def binum(bs)
>> result = 0
>> bs.unpack("cCC").each {|b| result = (result << | b }
>> result
>> end

>
> That's just crying out for inject():
>
> bs.unpack("cCC").inject(0) { |res, b| (res << | b }
>
>
>
> James Edward Gray II

Thanks,
ps. just bought your ruby quiz book

David Balmain
Guest
Posts: n/a

 08-02-2006
On 8/2/06, Kim Pedersen <(E-Mail Removed)> wrote:
> Dale Martenson wrote:
> > On Wednesday, August 02, 2006, at 5:46 AM, Kim Pedersen wrote:
> >
> >> 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 << | 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.

For variable length;

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