每次用到了再写, 总觉得在干无用的事情, 这次, 写了一个比较通用的, 备份下来..也分享出来....有缺陷/不足请指正...
<?php /* +----------------------------------------------------------------------+ | 位域运算库函数 | +----------------------------------------------------------------------+ | 提供位域运算能力 | | 此lib提供的函数基于以下前提 | | 1. 所有偏移量都是从右向左计算 | | 2. 所有偏移量都从0开始,即0代表最右面的第一位 | +----------------------------------------------------------------------+ | authors: selfimpr <[email protected]> | | 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 <[email protected]> | | 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);