【原创】PHP大数加减乘除余 -- 采用数组模拟的方式

PHP大数加减乘除

出了bcxxx以外, 可以利用数组进行运算

需要说明的是

  • 数组的每一个数对应真实十进制数的每一位,数组索引为0,表示个位,数组索引为1,表示十位,索引为2,表示百位,以此类推
  • 此段代码是对C语言的改写,感谢开源的博客(很对不起那篇博主,我忘记那篇C语言的代码出自何处了)
  • 代码需要改进的地方
    1. 对高位的0未做处理
    2. 处理效率低,拟之后用数组里面一个数表示多位十进制数优化
    3. 对于除法,商和余数目前是分开的,以后可以合并
function cmp($a, $b)//比较两个数的大小
{
    $lena = count($a);
    $lenb = count($a);
    for(; $lena>0 && $a[$lena-1]==0; $lena--);
    for(; $lenb>0 && $b[$lenb-1]==0; $lenb--);
    if($lena<$lenb)
        return -1;
    else if($lena==$lenb)
    {
        for($i=$lena-1; $i>=0; $i--)
            if($a[$i]>$b[$i])
                return 1;
            else
                if($a[$i]<$b[$i])
                    return -1;
        return 0;
    }
    else return 1;
}

function sub($a,$b) {
    $lena = count($a);
    $lenb = count($b);
    for(; $a[$lena-1]==0 && $lena>=0; $lena--);
    for(; $b[$lenb-1]==0 && $lenb>=0; $lenb--);
    $flag=cmp($a,$b);
    if($flag==0) {
        $c[0]=0;
        return $c;
    }
    if($flag==1) {
        for ($i=0;$i<$lenb;$i++) {
            if($a[$i]<$b[$i]){
                $a[$i+1]--;
                $a[$i]+=10;
            }
            $a[$i]-=$b[$i];
        }
        while($lena>0&&$a[$lena-1]==0)$lena--;
        return $a;
    }
}



function numcpy($p, $q, $det) {
    $lenp = count($p);
    $lenq = count($q);
    for(; $p[$lenp-1]==0 && $lenp-1>=0; $lenp--);
    for($i=0; $i<$lenq; $i++)
        $q[$i] = 0;
    for ($i=0;$i<$lenp;$i++) {
        $q[$i+$det]=$p[$i];
    }
    return $q;
}

function mod($a,$b) {
    //商的位数不超过被除数的位数-除数的位数+1
    $lenc = count($a)-count($b)+1;
    $tmp = $a;
    for($i=0;$i<$lenc;$i++){
        $c[$i] = 0;
    }
    for ($i=$lenc-1;$i>=0;$i--)//每次循环确定某位商的的值,从高位开始?
    {
        $tmp = numcpy($b,$tmp, $i);
        while(cmp($a,$tmp)>=0) {
            $c[$i]++;
            $a = sub($a,$tmp);
        }
    }
    return $a;
}

function div($a,$b) {
    //商的位数不超过被除数的位数-除数的位数+1
    $lenc = count($a)-count($b)+1;
    $tmp = $a;
    for($i=0;$i<$lenc;$i++){
        $c[$i] = 0;
    }
    for ($i=$lenc-1;$i>=0;$i--)//每次循环确定某位商的的值,从高位开始?
    {
        $tmp = numcpy($b,$tmp, $i);
        while(cmp($a,$tmp)>=0) {
            $c[$i]++;
            $a = sub($a,$tmp);
        }
    }
    return $c;
}


//大整形相加
function add($a, $b)
{
    $len_a = count($a);
    $len_b = count($b);
    if ($len_a > $len_b)
    {
        return add($b, $a);
    }
    else
    {
        $c = $b;
        for ($i=0; $i < $len_a; $i++)
        {
            $c[$i] += $a[$i];
            $c[$i+1] += (int)($c[$i] / 10);
            $c[$i] %= 10;
        }
        return $c;
    }
}

//相乘后再取模
function mul($a, $b)
{
    $lena = count($a);
    $lenb = count($b);
    $lenc = $lena+$lenb;
    for($i=0;$i<$lenc;$i++)
        $c[$i] = 0;
    for($i=0;$i<$lena;$i++)
    {
        for($j=0;$j<$lenb;$j++)
        {
            $c[$i+$j] += $a[$i] * $b[$j];
        }
    }
    for ($i=0; $i < $lenc; $i++)
    {
        $c[$i+1] += (int)($c[$i] / 10);
        $c[$i] %= 10;
    }
    return $c;
}

function equals_zero($arr)
{
	$len = count($arr);
	for($i=0; $i<$len; ++$i)
		if ($arr[$i])
			return 0;
	return 1;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

A.Star

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值