0

I would like to write a function to 'decode' bit mask into original values, e.g.
We have number and text attached to it:

  • 2 - Text_1
  • 4 - Text_2
  • 8 - Text_3
  • 16 - Text_4
  • 32 - Text_5

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?

2
  • Have you tried to write anything yourself? Commented Jun 25, 2019 at 18:55
  • What do you exactly want as output?Can you make it more clear? Do you want 48 as Text_5 and Text_4 or 32 and 16? Or Both? Commented Jun 25, 2019 at 19:20

3 Answers 3

3

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 ) 
Sign up to request clarification or add additional context in comments.

Comments

1

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; } } 

2 Comments

How on earth is this the accepted answer over mine below. shakes head (it only works for a fixed set of inputs). @Paul, if you are being graded for your answer, this is not a good one.
@lufc, you missed the point of the question. I have also some side comments about performance, but I'm here not to discuss your answer.
0

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.