David Balmain
8/2/2006 1:01:00 AM
On 8/2/06, Kim Pedersen <kimersen@online.no> 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 << 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.
For variable length;
c.unpack("cC*").inject(0) { |res, b| (res << 8) | b }