本文已参加“新人创作盛典”活动,共同开启鹈鹕创作之路。
1.问题描述
问题:编写一个函数来判断两个给定的数字是否具有相同的符号,而不直接使用比较运算符或与 0 进行比较。
例如 is_same_symbol(-1, 10) == false; is_same_symbol(10,20)=true; is_same_symbol(-1,-10)=true; 同时规定0为负数。
2.解决问题
在二进制表示中,如果最低位为1,则为正数。 如果最高位为0,则为负数。 所以我可以想办法通过位运算来区分。 1^0 = 1。所以负数^正数=负数。 其实和加法类似。
1. 位运算符
位运算符允许对整数中的指定位进行求值和操作。
示例 名称 结果
$a 和 $b
与(按位与)
将 $a 和 $b 中的位设置为 1 到 1。
$a | $b
或(按位或)
将设置 $a 和 $b 中任何 1 到 1 的位。
$a^$b
异或(按位异或)
会将 $a 和 $b 中的位设置为 1,其他位设置为 0 到 1。
〜$a
非(按位求反)
将 $a 中的位设置为 0 到 1,反之亦然。
$a > $b
右移
将$a中的位向右连接$b次(每次连接意味着“除以2”)。
位移是 PHP 中的物理操作。 向任何方向移出的位都会被丢弃。 左移两边都用零填充,并且符号位被删除,这意味着符号不被保留。 右移时,两边都用符号位填充,这意味着符号被保留。
使用括号确保所需的优先级。 例如,先比较$a & $b == true,然后按位与; while ($a & $b) == true 先按位计算,然后比较。
如果&、|、^运算符的左右操作数都是字符串php 位运算符,则对组成字符串的字符的ASCII值进行运算,结果也是字符串。 此外,两个操作数都将是,并且结果将是一个整数。
如果~运算符的操作数是字符串php 位运算符,则将对组成该字符串的字符的ASCII值进行运算,结果为字符串,否则操作数和结构体均为整数。
运算符的操作数和结果仍然是整数。
2.方法封装
确定可以使用位运算^来处理,则封装函数如下:
function is_same_symbol($a,$b){
return (($a ^ $b) > 0);
}
$a=12;
$b=-10;
if (is_same_symbol($a, $b) == true){
printf ("same symbol");
}else{
printf ("not same symbol");
}
这里使用了比较运算符(^)。 其实我们完全可以简化,去掉函数中>0的判断比较,因为我们只需要知道第一个符号位即可。
function is_same_symbol($a,$b){
return !(($a ^ $b) >> 31);
}
右移 31 位,仅保留最高符号位,即 0 或 1。
另外,如果你处理的数字不是数字而是字符串数字,比如$a="100.01"、$b="-10.01",那么只需要将它们转换为数字即可。
【注意】使用位运算时要注意运算优先级。
结尾
如果您有任何疑问请在下方留言。