热搜:NVER node 开发 php

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

2024-09-22 12:20:01
【分享】PHP int 超大溢出整数的 加减运算函数,如果有更好的方法欢迎探讨

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 已经提供了 BC 和 GMP 两个高精度数学运算函数库

bcadd ? Add two arbitrary precision numbersbccomp ? Compare two arbitrary precision numbersbcdiv ? Divide two arbitrary precision numbersbcmod ? Get modulus of an arbitrary precision numberbcmul ? Multiply two arbitrary precision numberbcpow ? Raise an arbitrary precision number to anotherbcpowmod ? Raise an arbitrary precision number to another, reduced by a specified modulusbcscale ? Set default scale parameter for all bc math functionsbcsqrt ? Get the square root of an arbitrary precision numberbcsub ? Subtract one arbitrary precision number from another
gmp_abs ? Absolute valuegmp_add ? Add numbersgmp_and ? Bitwise ANDgmp_clrbit ? Clear bitgmp_cmp ? Compare numbersgmp_com ? Calculates one's complementgmp_div_q ? Divide numbersgmp_div_qr ? Divide numbers and get quotient and remaindergmp_div_r ? Remainder of the division of numbersgmp_div ? 别名 gmp_div_qgmp_divexact ? Exact division of numbersgmp_fact ? Factorialgmp_gcd ? Calculate GCDgmp_gcdext ? Calculate GCD and multipliersgmp_hamdist ? Hamming distancegmp_init ? Create GMP numbergmp_intval ? Convert GMP number to integergmp_invert ? Inverse by modulogmp_jacobi ? Jacobi symbolgmp_legendre ? Legendre symbolgmp_mod ? Modulo operationgmp_mul ? Multiply numbersgmp_neg ? Negate numbergmp_nextprime ? Find next prime numbergmp_or ? Bitwise ORgmp_perfect_square ? Perfect square checkgmp_popcount ? Population countgmp_pow ? Raise number into powergmp_powm ? Raise number into power with modulogmp_prob_prime ? Check if number is "probably prime"gmp_random ? Random numbergmp_scan0 ? Scan for 0gmp_scan1 ? Scan for 1gmp_setbit ? Set bitgmp_sign ? Sign of numbergmp_sqrt ? Calculate square rootgmp_sqrtrem ? Square root with remaindergmp_strval ? Convert GMP number to stringgmp_sub ? Subtract numbersgmp_testbit ? Tests if a bit is setgmp_xor ? Bitwise XOR