I actually liked this question a lot as it got me thinking of various approaches. First I started tinkering with plain old binary and hex math, the >> operator, counting number of bits needed to represent any unsigned integer, etc. It took me back to high school Comp Sci classes.

A quick diversion: If you have a given resolution (say four bits, which is what is needed to represent one hex digit, as in the OP's example), you can calculate number of bits needed to represent any positive integer like this:

sub bits_needed { my ( $unsigned, $resolution ) = @_; my $bits_needed = floor( log2( $unsigned ) ) + 1; $bits_needed += $resolution - $bits_needed % $resolution if defined $resolution; return $bits_needed; }

Of course for that we need floor(), so we may use POSIX, and we also need log2() which is implemented as:

sub log2 { my $n = shift; return log($n)/log(2); }

But that's just a tangent that the original question drove me toward as I explored, and has nothing to do with the solution I ended up playing with.

We already had a pack and unpack solution, so I wanted to see what else is out there.

Back to the point: Introducing the CPAN. I found Bit::Vector. What a cool module! It makes bit twiddling simple.

Here's an example:

use strict; use warnings; use Bit::Vector; use Text::Template; use v5.12; my $orig_hex = "6bf"; my ( $reverse, $details ) = hex_reverse_bitwise( $orig_hex, 12 ); print Text::Template->fill_this_in( do{ undef $/; <DATA> }, HASH => $details, ); # Return bitwise reversed hex digits in scalar context. # In list context, return reversed hex digits plus a hashref # containing more detailed analysis. sub hex_reverse_bitwise { my ( $start, $bit_size ) = @_; my $orig_vec = Bit::Vector->new_Hex( $bit_size, $orig_hex ); my $rev_vec = Bit::Vector->new( $bit_size ); $rev_vec->Reverse( $orig_vec ); my $reversed = $rev_vec->to_Hex; return( $reversed, wantarray() ? { orig_hex => $orig_hex, orig_bits => $orig_vec->to_Bin, reversed_bits => $rev_vec->to_Bin, new_hex => $reversed, } : () ); } __DATA__ Given the hex digits '{lc $orig_hex}' with a bit representation of '{$orig_bits}', reversing the bits to '{$reversed_bits}' we get a hex representation of '{lc $new_hex}'.

The output is:

Given the hex digits '6bf' with a bit representation of '011010111111', reversing the bits to '111111010110' we get a hex representation of 'fd6'.

I had a little fun with Text::Template while I was at it. It's hard to beat the raw throughput of pack and unpack, but the Bit::Vector approach abstracts away some of the complexity.

Thanks for the motivation to tinker.


Dave


In reply to Re: LSB to MSB by davido
in thread LSB to MSB by Anonymous Monk

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.