in reply to Re: Extracting Bit Fields (Again)
in thread Extracting Bit Fields (Again)
This is the approach I’d take, as well.
Now if you go one step further, you can reorder and rewrite this like so:
$D3 = ( $num >> 0 ) & ( 1 << 4 ) - 1; # 4 bits starting at bit 0 $D2 = ( $num >> 4 ) & ( 1 << 3 ) - 1; # 3 bits starting at bit 4 $D1 = ( $num >> 7 ) & ( 1 << 1 ) - 1; # 1 bit starting at bit 7
And then destructively rewrite the input:
$D3 = $num & ( 1 << 4 ) - 1; # 4 bits starting at bit 0 $num = $num >> 4; $D2 = $num & ( 1 << 3 ) - 1; # 3 bits starting at bit 4 $num = $num >> 3; $D1 = $num & ( 1 << 1 ) - 1; # 1 bit starting at bit 7 $num = $num >> 1;
Hmm…
@width = ( 4, 3, 1 ); $D3 = $num & ( 1 << $width[ 0 ] ) - 1; # 4 bits starting at bit 0 $num = $num >> $width[0]; $D2 = $num & ( 1 << $width[ 1 ] ) - 1; # 3 bits starting at bit 4 $num = $num >> $width[ 1 ]; $D1 = $num & ( 1 << $width[ 2 ] ) - 1; # 1 bit starting at bit 7 $num = $num >> $width[ 2 ];
So obviously:
sub bitfield { my ( $num, @field ) = @_; my @value; for my $width ( @field ) { push @value, $num & ( 1 << $width ) - 1; $num = $num >> $width; } return @value; }
Unfortunately, this works only for bitfields up to the architecture integer size. It is possible with some contortions to cut fields from a string longer than 32 or 64 bits if you pluck the right pieces out manually, but no individual bitfield can ever be longer than 32/64 bits.
Makeshifts last the longest.
|
|---|