【原創】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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章