PHP大數加減乘除
出了bcxxx以外, 可以利用數組進行運算
需要說明的是
- 數組的每一個數對應真實十進制數的每一位,數組索引爲0,表示個位,數組索引爲1,表示十位,索引爲2,表示百位,以此類推
- 此段代碼是對C語言的改寫,感謝開源的博客(很對不起那篇博主,我忘記那篇C語言的代碼出自何處了)
- 代碼需要改進的地方
- 對高位的0未做處理
- 處理效率低,擬之後用數組裏面一個數表示多位十進制數優化
- 對於除法,商和餘數目前是分開的,以後可以合併
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;
}