加减乘除实现算法(整数)
一个数的相反数: 2的相反数的获取: add(~2,1)
加法:
由a^b可得按位相加后没有进位的和;
由a&b可得可以产生进位的地方;
由(a&b)<<1得到进位后的值。
那么 按位相加后原位和+进位和 就是加法的和了,而 a^b + (a&b)<<1 相当于把 + 两边再代入上述三步进行加法计算。直到进位和为0说明没有进位了则此时原位和即所求和。
function add($a,$b)
{
$sum = $a;
while($b != 0){
$sum = $a ^ $b;
$b = ($a & $b) << 1;
$a = $sum;
}
return $sum;
}
减法
function minus($a,$b)
{
$res = add($a,add(~$b,1));
return $res;
}
正整数乘法
function pos_multi($a,$b)
{
$res = 0;
while($b != 0){
if(($b & 1)!=0){
$res = add($res,$a);
}
$a <<= 1;
$b >>=1;
}
return $res;
}
乘法
function multi($a,$b)
{
if($a >= 0 && $b >= 0){
return pos_multi($a,$b);
}else if($a < 0){
if($b < 0){
return pos_multi(add(~$a,1),add(~$b,1));
}
return add(~pos_multi(add(~$a,1),$b),1);
}
return add(~pos_multi($a,add(~$b,1)),1);
}
正整数除法
function pos_div($a,$b)
{
$ans = 0;
for($i=31;$i>=0;$i--){
if(($a>>$i) >= $b){
$ans = $ans + (1 <<$i);
$a = $a - ($b <<$i);
}
}
return $ans;
}
正整数除法二:
function test_div($a,$b)
{
$ans = 0;
while($a >= $b){
a = minus($a,$b);
$ans = add($ans,1);
}
return $ans;//$ans是商,此时的$a是余数
}
//除法
function div($a,$b)
{
if($b == 0){
return "被除数不能是0";
}
if($a >= 0 && $b > 0){
return pos_div($a,$b);
}else if($a < 0){
if($b < 0){
return pos_div(add(~$a,1),add(~$b,1));
}else{
return add(~pos_div(add(~$a,1),$b),1);
}
}
return add(~pos_div($a,add(~$b,1)),1);
}