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.
In reply to Re^2: Extracting Bit Fields (Again)
by Aristotle
in thread Extracting Bit Fields (Again)
by ozboomer
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |