PHP位域操作函数封装

每次用到了再写, 总觉得在干无用的事情, 这次, 写了一个比较通用的, 备份下来..也分享出来....有缺陷/不足请指正...

<?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);



你可能感兴趣的:(PHP,json,function,user,单元测试,merge)