Reputation: 421
I would like to write a function to 'decode' bit mask into original values, e.g.
We have number and text attached to it:
Now I'm entering number e.g. 48
(32 + 16
) and I should get Text_5
and Text_4
so it's should return two numbers: 32
and 16
.
How to get this?
Upvotes: 0
Views: 826
Reputation: 1146
I guess, this is the simplest and most "native" implementation:
$array = [2 => 'Text_1', 4 => 'Text_2', 8 => 'Text_3', 16 => 'Text_4', 32 => 'Text_5'];
$number = 48;
foreach ($array as $mask => $string)
{
if ($number & $mask)
{
echo "$mask: $string" . PHP_EOL;
}
}
Upvotes: 1
Reputation: 430
Another option using only bit operators...
unmaskMe(48);
function unmaskMe(int $bitset) {
$bitOfsset = 0;
while ($bitset) {
if ($bitset & (1 << $bitOfsset)) {
echo 'Text_' . $bitOfsset . PHP_EOL;
$bitset &= ~(1 << $bitOfsset);
}
$bitOfsset++;
}
}
Outputs:
Text_4
Text_5
Upvotes: 0
Reputation: 2040
PHP has some functions to help with this, primarily decbin()
(https://www.php.net/manual/en/function.decbin.php) which will convert an integer to binary. You can then break that up into an array which will be numbered by the Text_
values from your example.
$input = 48;
$output = array_reverse(str_split(decbin($input)));
foreach ($output as $k => $v) {
echo $v ? "Text_$k".PHP_EOL : "";
}
So decbin(48)
would give 110000
, which you can break into the following array with str_split()
:
Array
(
[0] => 1
[1] => 1
[2] => 0
[3] => 0
[4] => 0
[5] => 0
)
But you can see this is backwards - in binary we number the bits from right to left, not left to right. So you need to reverse it, using array_reverse()
.
Then you have a nice array of Text_ => active (1 or 0)
pairs:
Array
(
[0] => 0
[1] => 0
[2] => 0
[3] => 0
[4] => 1
[5] => 1
)
Upvotes: 3