in reply to Re: Reading individual bits
in thread Reading individual bits

Sure thing, here's a program that shows basically how I use the function.
@ItemList = (); #this would be filled with some data already, and pass +ed in as a reference. $ItemListRef = \@ItemList; $LCSStatWd1 = 524288; #this would normally come from the file $LCSStatWd1Bits = unpack("B32",pack("N",$LCSStatWd1)); #creating the b +it string print "$LCSStatWd1Bits\n"; #Discretes $Offset = 0; $LidarPwrState = ReadBits($LCSStatWd1Bits,\$Offset,1,$ItemListRef); $LidarPwrStateToggle = ReadBits($LCSStatWd1Bits,\$Offset,1,$ItemListRe +f); $LCSMode = ReadBits($LCSStatWd1Bits,\$Offset,6,$ItemListRef); $LidarCondition = ReadBits($LCSStatWd1Bits,\$Offset,3,$ItemListRef); $NewCentAvail = ReadBits($LCSStatWd1Bits,\$Offset,1,$ItemListRef); $ObjOutOfScnWin = ReadBits($LCSStatWd1Bits,\$Offset,1,$ItemListRef); $ReAcqFailed = ReadBits($LCSStatWd1Bits,\$Offset,1,$ItemListRef); $LaserState = ReadBits($LCSStatWd1Bits,\$Offset,1,$ItemListRef); $GrCommEnable = ReadBits($LCSStatWd1Bits,\$Offset,1,$ItemListRef); $LidarMode = ReadBits($LCSStatWd1Bits,\$Offset,2,$ItemListRef); $LCSSubMode = ReadBits($LCSStatWd1Bits,\$Offset,3,$ItemListRef); $GNCpredit = ReadBits($LCSStatWd1Bits,\$Offset,1,$ItemListRef); $FOVedgemAz = ReadBits($LCSStatWd1Bits,\$Offset,1,$ItemListRef); $FOVedgepAz = ReadBits($LCSStatWd1Bits,\$Offset,1,$ItemListRef); $FOVedgemEl = ReadBits($LCSStatWd1Bits,\$Offset,1,$ItemListRef); $FOVedgepEl = ReadBits($LCSStatWd1Bits,\$Offset,1,$ItemListRef); $Spare2 = ReadBits($LCSStatWd1Bits,\$Offset,6,$ItemListRef); sub ReadBits { my $BitStringIn = @_[0]; my $OffsetRef = @_[1]; my $Length = @_[2]; my $ItemListRef = @_[3]; my $BitStringOut = 0; $BitStringOut = substr($BitStringIn,$$OffsetRef,$Length); $$OffsetRef += $Length; $NumZeros = 32-$Length; $Zeros = unpack("B$NumZeros",pack("N",0)); $BitStringOut = $Zeros.$BitStringOut; $NumOut = unpack("N",pack("B32",$BitStringOut)); @$ItemListRef = (@$ItemListRef,$NumOut, "\t"); print "\n$NumOut"; return($NumOut); }
I did look at vec, however it didn't look like it would work for me since I sometimes read 3 or 6 bits. I'll try taking out the padding, I thought that each number would need to be the same length to do the conversion right.

Replies are listed 'Best First'.
Re^3: Reading individual bits
by BrowserUk (Patriarch) on Jul 30, 2004 at 00:52 UTC

    This performs bit mask operations upon 32-bit values thereby saving the need to ascii-ize the binary.

    #! perl -slw use strict; sub getBits { my( $N32, $offset, $bits ) = @_; my $mask = 1 << $bits; $mask--; $mask <<= $offset; return ( $N32 & $mask ) >> $offset; } ## Encode some test data. my $data = unpack 'N', pack 'b*', #0123456789 123456789 123456789 1 '11101111101111111011111111101111'; # 7 31 127 511 15 print $data; ## 4160617975 print getBits( $data, 0, 3 ); ## Should be 7 print getBits( $data, 4, 5 ); ## should be 31 print getBits( $data, 10, 7 ); ## Should be 127 print getBits( $data, 18, 9 ); ## Should be 511 print getBits( $data, 28, 4 ); ## Should be 15 __END__ P:\test>test 4160617975 7 31 127 511 15

    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "Think for yourself!" - Abigail
    "Memory, processor, disk in that order on the hardware side. Algorithm, algoritm, algorithm on the code side." - tachyon
Re^3: Reading individual bits
by BrowserUk (Patriarch) on Jul 30, 2004 at 01:17 UTC

    Whilst I'm looking, this bit of code is very strange--and slow.

    @$ItemListRef = (@$ItemListRef,$NumOut, "\t");

    You

    1. pass in a reference to an array,
    2. dereference that array to produce a list,
    3. tack the latest value and a tab onto the end of the list
    4. and then assign that back to the original array.

    This action is the same as doing:

    push @$ItemListRef, $NumOut, "\t";

    Accept that it uses gob-loads (tech. term) of memory in building lots of intermediate lists in the process. No wonder your subroutine is slow.

    Also, why are you interspersing your values with tabs?

    If the intention is to print them as tab-delimited list to a file or the screen. Just build the array without the inspersed tabs and then use join to add teh tabs when you print.

    print join "\t", @ItemList;

    Not only will you save half the memory of your list, by not allocating it you'll save a bit more time.


    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "Think for yourself!" - Abigail
    "Memory, processor, disk in that order on the hardware side. Algorithm, algoritm, algorithm on the code side." - tachyon
      you can also use perl's $, variable to set the "output field seperator" to put tabs in between a elements passed to print in a list.

      i.e.

      rather than:
      print join "\t", @ItemList;

      you could do:
      local $, = "\t"; print @ItemList;

      doing a quick profile of these showed only a 3-4% increase in speed so code readability might outweigh performance in this case