|
每次用到了再写, 总觉得在干无用的事情, 这次, 写了一个比较通用的, 备份下来..也分享出来....有缺陷/不足请指正...
<?php/*+----------------------------------------------------------------------+| 位域运算库函数 |+----------------------------------------------------------------------+| 提供位域运算能力 || 此lib提供的函数基于以下前提 || 1. 所有偏移量都是从右向左计算 || 2. 所有偏移量都从0开始,即0代表最右面的第一位 |+----------------------------------------------------------------------+| authors: selfimpr <leiguoguo@yahoo.com.cn> || blog: http://blog.csdn.net/lgg201 |+----------------------------------------------------------------------+*//*** 保留$target中从$offset开始的$limit位, 其余位置0* @param int $target 操作数* @param int $offset 偏移量* @param int $limit 保留总位数* @return int计算结果*/function bit_remain_range(&$target, $offset, $limit) {return $target &= (pow(2, $limit) - 1) << $offset;}/*** 将$target中从$offset开始的$limit位设置为0, 其余位不变* @param int $target 操作数* @param int $offset 偏移量* @param int $limit 清理总位数* @return int计算结果*/function bit_clear_range(&$target, $offset, $limit) {return $target &= ~ ((pow(2, $limit) - 1) << $offset);}/*** 将$target中的第$order位置为0* @param int $target 操作数* @param int $order 要操作的位的偏移量* @return int计算结果*/function bit_clear_single(&$target, $order) {return bit_clear_range($target, $order, 1);}/*** 将$mask中的$offset起的$limit位合并到$target的对应位置* @param int $target 操作数* @param int $mask 要合并的值* @param int $offset 偏移量* @param int $limit 合并总位数* @return int计算结果*/function bit_merge_range(&$target, $mask, $offset, $limit) {bit_remain_range($mask, $offset, $limit);bit_clear_range($target, $offset, $limit);return $target |= $mask;}/*** 将$mask的低$limit位合并到$target的$offset起的$limit位中* @param int $target 操作数* @param int $mask 要合并的值* @param int $offset 偏移量* @param int $limit 合并总位数* @return int计算结果*/function bit_set_range(&$target, $mask, $offset, $limit) {bit_remain_range($mask, 0, $limit);return bit_merge_range($target, $mask << $offset, $offset, $limit);}/*** 设置$target的$order位为1* @param int $target 操作数* @param int $order 要操作的位* @return int计算结果*/function bit_set_single(&$target, $order) {return bit_set_range($target, 1, $order, 1);}/*** 计算$target中从$offset起的$limit位值是否等于$value* @param int $target 操作数* @param int $value 要比较的值* @param int $offset 偏移量* @param int $limit 总位数* @return bool比较结果(相等true)*/function bit_check_range($target, $value, $offset, $limit) {bit_remain_range($target, $offset, $limit);$target >>= $offset;return $target == $value;}/*** 检查$target的第$order位是否为1* @param int $target 操作数* @param int $order 要检查的位* @return bool比较结果(是1返回true)*/function bit_check_single($target, $order) {return (bool)bit_remain_range($target, $order, 1);}
下面是一个简单的单元测试
<?php/*+----------------------------------------------------------------------+| 位域运算库函数单元测试 |+----------------------------------------------------------------------+| 提供位域运算能力 || 此lib提供的函数基于以下前提 || 1. 所有偏移量都是从右向左计算 || 2. 所有偏移量都从0开始,即0代表最右面的第一位 |+----------------------------------------------------------------------+| authors: selfimpr <leiguoguo@yahoo.com.cn> || blog: http://blog.csdn.net/lgg201 |+----------------------------------------------------------------------+*/require dirname(__FILE__) . '/bit_lib.php';function test_bit1($method) {$args= func_get_args();$func= $args[0];$target= $args[1];$args= array_slice($args, 1);printf("%s:\n%032b\n%032b\n\n", "$func(" . implode(', ', $args) . ")", $target, call_user_func_array($func, $args));}function test_bit2($method) {$args= func_get_args();$func= $args[0];$target= $args[1];$mask= $args[2];$args= array_slice($args, 1);printf("%s:\n%032b\n%032b\n%032b\n\n", "$func(" . implode(', ', $args) . ")", $target, $mask, call_user_func_array($func, $args));}function test_bit3($method) {$args= func_get_args();$func= $args[0];$target= $args[1];$args= array_slice($args, 1);printf("%s:\n%032b\n%s\n\n", "$func(" . implode(', ', $args) . ")", $target, json_encode(call_user_func_array($func, $args)));}function test_bit4($method) {$args= func_get_args();$func= $args[0];$target= $args[1];$mask= $args[2];$args= array_slice($args, 1);printf("%s:\n%032b\n%032b\n%s\n\n", "$func(" . implode(', ', $args) . ")", $target, $mask, json_encode(call_user_func_array($func, $args)));}#由于bit_lib中函数定义了引用传参, 测试用例为了书写方便没有传递引用, 因此会有警告.error_reporting(E_ALL & ~E_WARNING);test_bit1('bit_remain_range', 0xFFFFFFFF, 4, 8);test_bit1('bit_clear_range', 0xFFFFFFFF, 4, 8);test_bit1('bit_clear_single', 0xFFFFFFFF, 4);test_bit2('bit_merge_range', 0xFF00FF00, 0xFFFFF0FF, 4, 8);test_bit2('bit_set_range', 0xFF00FF00, 0xFFFFF0FF, 4, 16);test_bit1('bit_set_single', 0xFF00FF00, 4);test_bit3('bit_check_single', 0xFF00FF00, 8);test_bit4('bit_check_range', 0xFF00FF00, 0xF0, 4, 8); |
|