首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网站开发 > PHP >

PHP int 超大溢出整数的 加减运算函数,如果有更好的方法欢迎探讨

2013-09-07 
【分享】PHP int 超大溢出整数的 加减运算函数,如果有更好的方法欢迎探讨分享一个溢出整数加减的运算函数,刚

【分享】PHP int 超大溢出整数的 加减运算函数,如果有更好的方法欢迎探讨
分享一个溢出整数加减的运算函数,刚刚写的,对于溢出的整数可以用这个来进行加减运算。
遗憾的几点是:


一代码太多;
二只有加减运算,乘除取余都没有;



其实还有一个更简便的方式就是用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 溢出 加减运算 超大整数
[解决办法]
php 已经提供了 BC 和 GMP 两个高精度数学运算函数库

bcadd — Add two arbitrary precision numbers
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

热点排行