如何获取十进制数字列表“;隐藏的“;PHP中的二进制数


How to get list of decimal numbers "hidden" in binary number in PHP?

首先,我对这个问题的标题写得不好深表歉意。因此,请有英语母语的人适当地更改标题。我的问题很简单,如下所示:

我正在使用integer来存储一个项目的多种类型。例如:

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

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

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

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

提前感谢您的帮助。

这里有一个没有任何循环的函数(主要是为了好玩:(:

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
}

然而,这并不意味着它是有效的。如果您使用位掩码,则最好使用位运算符(如位运算符和(&((来检查值。例如,如果你想检查你的整数是否包含类型D和类型E,你应该进行

if ($integer & 8 & 16)

为了检查每个单独的类型,我会给我们一个带有位移算子的循环

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

怎么样?http://codepad.org/AzgdPsL1

解释发生了什么:

  1. 我创建了一个包含1到$max_bit位范围内所有有效类型的$types数组
  2. 当数字大于0时进行循环,它将与1进行逐位"与"运算。如果结果为true,这意味着LSB已设置,因此$type数组开头的type适用于此数字。当前类型将添加到返回数组中
  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));
    

输出(针对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"
}
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']));

只需确保将从数据库中获取的值强制转换为integer即可。

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

$set = array();
foreach ($types as $key => $value)
    if (check_flag($db_value, $value)) $set[] = $key;
$a = 10;
$scan = 1;
$result = array();
while ($a >= $scan){
    if ($a & $scan)
        $result[] = $scan;
        $scan<<=1; //just a bit shift
}
var_dump($result);