分享一个溢出整数加减的运算函数,刚刚写的,对于溢出的整数可以用这个来进行加减运算。
遗憾的几点是:一代码太多;
二只有加减运算,乘除取余都没有;其实还有一个更简便的方式就是用SQL数据库的:SELECT n1+n2;mysql> SELECT 11234123413241341234123412341234+1;
+------------------------------------+
| 11234123413241341234123412341234+1 |
+------------------------------------+
| 11234123413241341234123412341235 |
+------------------------------------+
1 row in set (0.00 sec)
mysql> SELECT 11234123413241341234123412341234*12341234123;
+----------------------------------------------+
| 11234123413241341234123412341234*12341234123 |
+----------------------------------------------+
| 138642947209487270472850788378836360727782 |
+----------------------------------------------+
1 row in set (0.00 sec)
如果有更好的方法,请随时回帖或者发个信息给我。欢迎探讨。
/* big int operate [by fuzb 20130826] */
function bigintO($num1,$op,$num2)
{
$arr = array();
$endop = '';
$num1o = $num1;
$num2o = $num2;
if($num1 < 0)
{
$c1 = -1;
$num1 = preg_replace('/^(-)/','',$num1); } else {
$c1 = 1;
} if($num2 < 0)
{
$c2 = -1;
$num2 = preg_replace('/^(-)/','',$num2);
} else {
$c2 = 1;
} $len1 = strlen($num1);
$len2 = strlen($num2);
$len = max(strlen($num1),strlen($num2));
if($len1 < $len) $num1 = str_pad('0',$len - $len1).$num1;
if($len2 < $len) $num2 = str_pad('0',$len - $len2).$num2;
if($op == '+')
{
if($c1 == $c2)
{
$endop = $c1 > 0 ? '':'-';
} else {
$endop = abs($num1o) > abs($num2o) ? $c1:$c2;
$endop = $endop > 0 ? '':'-';
}
$cc = $endop == '-' ? -1:1; for($i=0; $i< $len; $i++)
{
$n1 = intval($num1{$i});
$n2 = intval($num2{$i});
$n = $n1*$c1+$n2*$c2;
$arr[$i] = $n*$cc;
} } else if($op == '-') { if($c1 < 0)
{
$endop = $c2 > 0 ? '-':(abs($num1o) > abs($num2o) ? '-':'');
} else {
$endop = $c2 > 0 ? (abs($num1o) > abs($num2o) ? '':'-'):'';
}
$cc = $endop == '-' ? -1:1; for($i=0;$i < $len;$i++)
{
$n1 = intval($num1{$i});
$n2 = intval($num2{$i});
$n = $n1*$c1-$n2*$c2;
$arr[$i] = $n*$cc;
}
} $len = count($arr);
$arr2 = array();
for($i=0;$i< $len;$i++)
{
if($arr[$i] < 0) {
$n = $arr[$i] + 10; $arr2[$i] = $n;
$j = $i-1;
while(true)
{
if($arr2[$j] == 0)
{
$arr2[$j] = 9;
$j--; } else { $arr2[$j]--;
break;
}
} } else if($arr[$i] > 9) { $n = $arr[$i] - 10; $arr2[$i] = $n;
$j = $i-1;
while(true)
{
if($arr2[$j] == 9)
{
$arr2[$j] = 0;
$j--; } else { $arr2[$j]++;
break;
}
} } else { $arr2[$i] = $arr[$i];
}
} $value = $endop.preg_replace('/^(0{1,})/','',implode($arr2));
return strlen($value) > 0 ? $value : '0';
}
测试:$a = '-12345678901234567890123456789';
$b = '1';
$c = bigintO($a,'+',$b);var_dump($a);
var_dump($b);
var_dump($c);
exit();
/*
输出:
string '-12345678901234567890123456789' (length=30)string '1' (length=1)string '-12345678901234567890123456788' (length=30)*/
PHP溢出加减运算超大整数
遗憾的几点是:一代码太多;
二只有加减运算,乘除取余都没有;其实还有一个更简便的方式就是用SQL数据库的:SELECT n1+n2;mysql> SELECT 11234123413241341234123412341234+1;
+------------------------------------+
| 11234123413241341234123412341234+1 |
+------------------------------------+
| 11234123413241341234123412341235 |
+------------------------------------+
1 row in set (0.00 sec)
mysql> SELECT 11234123413241341234123412341234*12341234123;
+----------------------------------------------+
| 11234123413241341234123412341234*12341234123 |
+----------------------------------------------+
| 138642947209487270472850788378836360727782 |
+----------------------------------------------+
1 row in set (0.00 sec)
如果有更好的方法,请随时回帖或者发个信息给我。欢迎探讨。
/* big int operate [by fuzb 20130826] */
function bigintO($num1,$op,$num2)
{
$arr = array();
$endop = '';
$num1o = $num1;
$num2o = $num2;
if($num1 < 0)
{
$c1 = -1;
$num1 = preg_replace('/^(-)/','',$num1); } else {
$c1 = 1;
} if($num2 < 0)
{
$c2 = -1;
$num2 = preg_replace('/^(-)/','',$num2);
} else {
$c2 = 1;
} $len1 = strlen($num1);
$len2 = strlen($num2);
$len = max(strlen($num1),strlen($num2));
if($len1 < $len) $num1 = str_pad('0',$len - $len1).$num1;
if($len2 < $len) $num2 = str_pad('0',$len - $len2).$num2;
if($op == '+')
{
if($c1 == $c2)
{
$endop = $c1 > 0 ? '':'-';
} else {
$endop = abs($num1o) > abs($num2o) ? $c1:$c2;
$endop = $endop > 0 ? '':'-';
}
$cc = $endop == '-' ? -1:1; for($i=0; $i< $len; $i++)
{
$n1 = intval($num1{$i});
$n2 = intval($num2{$i});
$n = $n1*$c1+$n2*$c2;
$arr[$i] = $n*$cc;
} } else if($op == '-') { if($c1 < 0)
{
$endop = $c2 > 0 ? '-':(abs($num1o) > abs($num2o) ? '-':'');
} else {
$endop = $c2 > 0 ? (abs($num1o) > abs($num2o) ? '':'-'):'';
}
$cc = $endop == '-' ? -1:1; for($i=0;$i < $len;$i++)
{
$n1 = intval($num1{$i});
$n2 = intval($num2{$i});
$n = $n1*$c1-$n2*$c2;
$arr[$i] = $n*$cc;
}
} $len = count($arr);
$arr2 = array();
for($i=0;$i< $len;$i++)
{
if($arr[$i] < 0) {
$n = $arr[$i] + 10; $arr2[$i] = $n;
$j = $i-1;
while(true)
{
if($arr2[$j] == 0)
{
$arr2[$j] = 9;
$j--; } else { $arr2[$j]--;
break;
}
} } else if($arr[$i] > 9) { $n = $arr[$i] - 10; $arr2[$i] = $n;
$j = $i-1;
while(true)
{
if($arr2[$j] == 9)
{
$arr2[$j] = 0;
$j--; } else { $arr2[$j]++;
break;
}
} } else { $arr2[$i] = $arr[$i];
}
} $value = $endop.preg_replace('/^(0{1,})/','',implode($arr2));
return strlen($value) > 0 ? $value : '0';
}
测试:$a = '-12345678901234567890123456789';
$b = '1';
$c = bigintO($a,'+',$b);var_dump($a);
var_dump($b);
var_dump($c);
exit();
/*
输出:
string '-12345678901234567890123456789' (length=30)string '1' (length=1)string '-12345678901234567890123456788' (length=30)*/
PHP溢出加减运算超大整数
bccomp — Compare two arbitrary precision numbers
bcdiv — Divide two arbitrary precision numbers
bcmod — Get modulus of an arbitrary precision number
bcmul — Multiply two arbitrary precision number
bcpow — Raise an arbitrary precision number to another
bcpowmod — Raise an arbitrary precision number to another, reduced by a specified modulus
bcscale — Set default scale parameter for all bc math functions
bcsqrt — Get the square root of an arbitrary precision number
bcsub — Subtract one arbitrary precision number from another
gmp_abs — Absolute value
gmp_add — Add numbers
gmp_and — Bitwise AND
gmp_clrbit — Clear bit
gmp_cmp — Compare numbers
gmp_com — Calculates one's complement
gmp_div_q — Divide numbers
gmp_div_qr — Divide numbers and get quotient and remainder
gmp_div_r — Remainder of the division of numbers
gmp_div — 别名 gmp_div_q
gmp_divexact — Exact division of numbers
gmp_fact — Factorial
gmp_gcd — Calculate GCD
gmp_gcdext — Calculate GCD and multipliers
gmp_hamdist — Hamming distance
gmp_init — Create GMP number
gmp_intval — Convert GMP number to integer
gmp_invert — Inverse by modulo
gmp_jacobi — Jacobi symbol
gmp_legendre — Legendre symbol
gmp_mod — Modulo operation
gmp_mul — Multiply numbers
gmp_neg — Negate number
gmp_nextprime — Find next prime number
gmp_or — Bitwise OR
gmp_perfect_square — Perfect square check
gmp_popcount — Population count
gmp_pow — Raise number into power
gmp_powm — Raise number into power with modulo
gmp_prob_prime — Check if number is "probably prime"
gmp_random — Random number
gmp_scan0 — Scan for 0
gmp_scan1 — Scan for 1
gmp_setbit — Set bit
gmp_sign — Sign of number
gmp_sqrt — Calculate square root
gmp_sqrtrem — Square root with remainder
gmp_strval — Convert GMP number to string
gmp_sub — Subtract numbers
gmp_testbit — Tests if a bit is set
gmp_xor — Bitwise XOR