如何在PHP中获取二进制数中“隐藏”的十进制数列表?

时间:2011-11-08 13:14:11

标签: php numbers integer

首先,我非常抱歉我写的这个问题写得不好。所以请用英语为母语的人适当改变标题。我的问题很简单,如下:

我使用整数来存储多个类型的一个项目。例如:

TYPE A = 1
TYPE B = 2
TYPE C = 4
TYPE D = 8
TYPE E = 16
etc...

现在DB中的项目的类型值为14,这意味着它已被分配到TYPE B + C + D.如果它具有例如9的类型值,则意味着它已被分配给TYPE A + D.

我需要一个函数,我将提供单一类型的整数,这个函数将返回整数类型的数组。

我可以遍历所有整数并将它们与数字进行比较,但这就是我现在使用的,但我正在寻找一些更有效的方法,如果存在的话?

提前感谢您的帮助。

4 个答案:

答案 0 :(得分:1)

这是怎么回事? http://codepad.org/AzgdPsL1

解释发生了什么:

  1. 我创建了一个$types数组,其中包含1到$max_bit位范围内的所有有效类型。
  2. 当数字大于0时循环,它与1进行按位AND运算。如果结果是计算结果为true,则表示LSB已设置,因此type位于$type的前面。 1}}数组适用于此数字。当前类型将添加到返回数组中。
  3. 然后将数字向右移动一位。

    <?php
    
    function num2type( $num)
    {
        $max_bit = 5;
        $types = array_combine( range( 1, $max_bit), range( ord( 'A'), ord( 'A') + $max_bit - 1));
    
        $return = array();
        while( $num > 0)
        {
            $current_type = array_shift( $types);
            if( $num & 0x1)
            {
                $return[] = chr( $current_type);
            }
            $num = $num >> 1;
        }
        return $return;
    }
    
    var_dump( num2type( 8)); // array(1) { [0]=> string(1) "D" }
    var_dump( num2type( 31)); 
    var_dump( num2type( 14));
    
  4. 输出(31):

    array(5) {
      [0]=>
      string(1) "A"
      [1]=>
      string(1) "B"
      [2]=>
      string(1) "C"
      [3]=>
      string(1) "D"
      [4]=>
      string(1) "E"
    }
    

    输出14:

    array(3) {
      [0]=>
      string(1) "B"
      [1]=>
      string(1) "C"
      [2]=>
      string(1) "D"
    }
    

答案 1 :(得分:1)

$a = 10;
$scan = 1;
$result = array();
while ($a >= $scan){
    if ($a & $scan)
        $result[] = $scan;
        $scan<<=1; //just a bit shift
}
var_dump($result);

答案 2 :(得分:1)

function check_flag($field, $bit)
{
    return (($field | $bit) === $field) ? TRUE : FALSE;
}

$types = array('A' => 1, 'B' => 2, 'C' => 4, 'D' => 8, 'E' => 16);
$db_value = 14;
var_dump(check_flag($db_value, $types['B']));

...只需确保将从数据库获取的值转换为整数。

编辑:现在我读到你需要设置的所有类型,这里有更多的逻辑:

$set = array();
foreach ($types as $key => $value)
    if (check_flag($db_value, $value)) $set[] = $key;

答案 3 :(得分:1)

这是一个没有任何循环的函数(主要是为了它的乐趣:) :):

function getTypes($int)
{
    $types = array('Type A','Type B','Type C','Type D','Type E');//defining types
    $t = array_reverse(str_split(decbin($int)));//converting $int to an array of bits
    $types = array_slice($types,0,ceil(log($int,2)));//slicing the array to the same size as number of bits in the $int
    $t = array_combine($types,$t);// Creating a new array where types are keys and bits are values
    return array_keys($t,1);// returning an array of keys which have a value of 1
}

然而,这并不意味着它是有效的。如果使用位掩码,最好使用按位和(&amp;)等按位运算符检查值。 例如,如果要检查整数是否包含类型D和类型E,则应该执行

if ($integer & 8 & 16)

要检查每个单独的类型,我将使用bitshift运算符循环

function getTypes($int)
{
    $result = array();
    $types = array('Type A','Type B','Type C','Type D','Type E');
    foreach($types as $type)
    {
        if ($int & 1)//checking if last bit is 1 (exactly the same as if($int%2) )
            $result[]=$type;
        $int>>=1;//shifting integer's bits to the right (exactly the same as $int = $int / 2)
    }
    return $result;
}