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;
}