Simpler way to do this?

Do you have a question? Post it now! No Registration Necessary.  Now with pictures!

Threaded View

I'm sure theres a way to make this simpler but I haven't been able to
figure it out.....heres whats going on:

$tnum = array();
for($i = 0; $i < count($targets['id']); $i++)
    $tnum[] = hexdec($targets['flags'][$i]);
    $headr = substr(sprintf('%032b', $tnum[$i]), 0, -12);
    $footr = substr(sprintf('%012b', $tnum[$i]), -12);
    $fparts = str_split($binCode, 3);
    $hparts = str_split($headr, 4);
    echo "----
    echo "---<br />";

Basically, I'm taking these records out of sql, decoding one of the
columns that has hex values, into binary pieces that match a
particular flag.  Right now as an example, for "fparts" I'm just using
4 seperate Switch statements for is one of four:

    switch ($fparts[0])
    case '001':
      echo "value1 <br />";
    case '010':
      echo "value2 <br />";
    case '011':
      echo "value3 <br />";
    case '100':
      echo "value4 <br />";
    case '101':
      echo "value5 <br />";
    case '110':
      echo "value6 <br />";
      echo "NO DATA <br />";

So each value1-6 is something I need returned and placed into a new
sql column etc..  The echo's above can be replaced with a sql query
and so on, my problem is that I'm sure theres an easier way to do this
without using a hundred plus lines of code for 9 different switch
statements.  For instance maybe using logic operators to match the
flags(?)  Any help would be much appreciated, thanks!

Re: Simpler way to do this?

inexion wrote:

Quoted text here. Click to load it

Use array instead of switch,
$arr = array(
   "001" => "value 1",
   // ...
print isset($arr[$fparts[0]]) ? $arr[$fparts[0]] : "NO DATA";

Quoted text here. Click to load it

Re: Simpler way to do this?

.oO(Matija Papec)

Quoted text here. Click to load it

bindec() might be another option, dependent on what the OP wants to do.


Re: Simpler way to do this?

Thanks for the suggestions, I think I need to explain a little more
about what I need in the if statement.....

for example:

Flags column


so in binary, this field is being broken up like so:

00000000001000000001  001 000 001 001

The 4 sets of bits at the beginning here can be ignored, I'm concerned
with the 20 bits that remain.  Is there a way I could create a mask or
using logic be able to check whether a particular bit has been set in
that field?

In theory, the flags column could carry a set like.....0x00200209, or
0x00812209, I need to use wildcards or something to identify if for
instance the 8 has been set at that position, without having to make
an array of all the possible combinations the field could have......

hopefully thats possible, thanks again!

Re: Simpler way to do this?


Quoted text here. Click to load it

Checking if a bit is set is done with a logical AND:

if (($flags & BIT_VALUE) == BIT_VALUE) {

The shorter variant:

if ($flags & BIT_VALUE) {

will also work in this case, but doesn't return a boolean value and may
cause problems if you want to test for multiple bits at the same time.

Quoted text here. Click to load it

Do you mean the 8th bit?

Quoted text here. Click to load it

Define a meaningful constant for each bit, then use the logical AND
as shown above. IMHO it helps a lot to define such constants with hex
values (the decimal values are just shown for completeness):

define('BIT_1', 0x0001); // 2^0 = 1
define('BIT_2', 0x0002); // 2^1 = 2
define('BIT_3', 0x0004); // 2^2 = 4
define('BIT_4', 0x0008); // 2^3 = 8
define('BIT_5', 0x0010); // 2^4 = 16
define('BIT_6', 0x0020); // 2^5 = 32
define('BIT_7', 0x0040); // 2^6 = 64
define('BIT_8', 0x0080); // 2^7 = 128

Of course you should choose better names which represent the meaning of
the flags.


Re: Simpler way to do this?

Hey Micha,

Thanks a lot for all your help so far Micha, much appreciated!

The 8 in my example wasn't the eighth bit, but whatever place it was
in up there (6th bit i think)....but your idea is perfect and would
work just the same obviously.

So in your example, I would just need to define a bunch more of the
bits and use the bitwise logical AND in the if statement.

for example...

define('BIT_5', 0x00010); // 2^4 = 16
define('BIT_6', 0x00020); // 2^5 = 32
define('BIT_7', 0x00040); // 2^6 = 64
define('BIT_8', 0x00080); // 2^7 = 128

Here would be an if statement checking the fifth bit then....

if(($fparts[0] & BIT_5) == BIT_5){


This statement is just checking $fparts[0] to see if its 0x00010
though(?), does this mean I need an if statement for each...0x00020,
0x00040, and 0x00080?  Is there a way do it all at once?  Can I make a
combined OR statement perhaps?

Re: Simpler way to do this?


Quoted text here. Click to load it

You're welcome.

Correct. It will just check that particular bit, all others will be

Quoted text here. Click to load it

Exactly. You can test multiple bits at once by combining them with a
logical OR. In this case it might be easier to use a little function to
perform the test, something like

function hasFlag($flags, $value) {
  return ($flags & $value) == $value;

Then you can do things like:

if (hasFlag($fparts[0], BIT_6|BIT_7|BIT_8)) {
  // all three bits set

If some particular bit combinations are used quite regularly, then it
could make sense to define additional constants for such combinations,

define(BIT_678, BIT_6|BIT_7|BIT_8);

if (hasFlag($fparts[0], BIT_678)) {
  // all three bits set

To give a better real-life example: In a login system with various user
privileges there could be these bit constants to control the access to
some parts of the site or to a database record for example:

define('USER_ACCESS_READ',  0x0001);
define('USER_ACCESS_WRITE', 0x0002);

For convenience there could also be the combination of these both if you
want to check that a user has full access:

// or shorter: define('USER_ACCESS_RW', 0x0003);

There are a lot of useful things you can do with such bit manipulations.


Re: Simpler way to do this?

Ok so, I'm having a slight problem here - it seems like something is
offset somehow, I will show an example:

Using this mask...

define('TMONLY', 0x00800);

and this statement...

if(($hparts[0] & TMONLY) == TMONLY){

Ok, so then when I run this code, things are being marked on the page
"THIS SHOULD BE TMONLY" when that bit is obviously not set (for
example 601209), what could be going on?

I tried to break it down by creating a test page to make sure the
correct bits are being fed into it....for example....


$test = hexdec(601209);

$headr = substr(sprintf('%032b', $test), 0, -12);

echo $headr;


this outputs 0000 0000 0110 0000 0001 for the last 20 bits - as you
can see, 8 is not set here, but its returning to me as if it were for
some reason.  This is happening only for the 1,2,4,6, and 8's that are
set in that bit....i.e..

in binary...any variation of that field where 8 is set should be
setting it to true:

0000 0000 1000 0000 0000
0000 0000 1001 0000 0000
0000 0000 1010 0000 0000
0000 0000 1011 0000 0000

0000 0000 1100 0000 0000
0000 0000 1101 0000 0000
0000 0000 1110 0000 0000
0000 0000 1111 0000 0000

So why would something like the following set it off?

0000 0000 0010 0000 0000
0000 0000 0110 0000 0000

Sorry I'm just confused =/

Re: Simpler way to do this?

I fixed it, I think it has to do with the fact that I was comparing a
binary number against a hex I converted my binary number
back to hex and changed my mask to simple hex digits.....


define('TMONLY', 800);

    $tnum[] = hexdec($targets['flags'][$i]);
    $headr = substr(sprintf('%032b', $tnum[$i]), 0, -12);
    $footr = substr(sprintf('%012b', $tnum[$i]), -12);
    $fparts = str_split($footr, 3);
    $hparts = str_split($headr, 20);
    $hval = base_convert($hparts[0], 2, 16);

    if(($hval & TMONLY) == TMONLY){
    echo "THIS SHOULD BE 2MASS ONLY<br />";

Site Timeline