Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/blackberry/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在PHP中处理大量数据_Php_Bignum - Fatal编程技术网

在PHP中处理大量数据

在PHP中处理大量数据,php,bignum,Php,Bignum,若要按照使用大数字(100000+)时的要求使用,需要进行一些非常大的计算 当我将两个大数字相乘(例如:62574和62574)时,PHP似乎将结果转换为浮点数。获取返回奇怪值的的模数值 $x = 62574 * 62574; var_dump($x); // float(3915505476) ... correct var_dump($x % 104659); // int(-72945) ... wtf. 有没有办法让PHP正确执行这些计算?或者,是否有另一种方法可以

若要按照使用大数字(100000+)时的要求使用,需要进行一些非常大的计算

当我将两个大数字相乘(例如:62574和62574)时,PHP似乎将结果转换为浮点数。获取返回奇怪值的的模数值

$x = 62574 * 62574;
var_dump($x);          // float(3915505476) ... correct
var_dump($x % 104659); // int(-72945)  ... wtf.
有没有办法让PHP正确执行这些计算?或者,是否有另一种方法可以找到适用于大数的模数值?

我建议您试试。如果这不起作用,您可以使用添加用于大整数计算的C/C++代码,并将其链接到您的代码中。

您看了吗?php在32位平台上存在整数超过2^31-1的问题

var_dump(bcmod("$x", '104659') ); // string(4) "2968"

出于某种原因,PHP中有两个标准库处理任意长度/精度数字:和。我个人更喜欢GMP,因为它更新鲜,API更丰富

基于GMP,我已经实现了存储和处理货币金额(如100.25美元)。那里有很多mod计算,没有任何问题。使用非常大的数字进行测试。

使用此选项

 $num1 = "123456789012345678901234567890";
 $num2 = "9876543210";
 $r    = mysql_query("Select @sum:=$num1 + $num2");
 $sumR = mysql_fetch_row($r);
 $sum  = $sumR[0];

我找到了另一个解决方案,但数字将存储为字符串。一旦您将其转换回数值,您将受限于底层平台的精度。在32位平台上,可以表示为int类型的最大int为2147483647:

/**
 * @param string $a
 * @param string $b
 * @return string
 */
function terminal_add($a, $b){
    return shell_exec('echo "'.$a.'+'.$b.'"|bc');
}

// terminal_add("123456789012345678901234567890", "9876543210")
// output: "123456789012345678911111111100"

我为您编写了一个非常小的代码,在遇到大数字的情况下肯定会起作用-

<?php
    $x = gmp_strval(gmp_mul("62574","62574")); // $x="3915505476"
    $mod=gmp_strval(gmp_mod($x,"104659"));  //$mod="2968"

    echo "x : ".$x."<br>";
    echo "mod : ".$mod;

    /* Output:
        x : 3915505476
        mod : 2968
    */
?>

您只需使用字符串来存储大数字,并使用PHP中的GMP函数对其进行操作

您可以在这里的官方PHP手册中查看一些良好的GMP功能-




Nice(讽刺)…没有任何文档!注意:如您所见,这是因为
%
使用整数包装器。PHP的整数实现存在致命缺陷,1)完全依赖于平台(endianess和位大小)2)PHP只使用有符号整数,3)超出有符号整数的范围,致命的部分开始发挥作用,因为它会将结果转换为浮动。这意味着,如果你在32位系统上执行1+2147483647,你将得到一个浮点,这使得打包二进制数据“非常有趣”。现代用户可能会发现,他们无法在闪亮的现代64位机器上使用问题中的数字重现这种行为——事实上,当他们
var_dump($x)时,他们可能会发现
它们得到的是整数,而不是浮点数。但是,如果他们尝试执行
$x=PHP\u INT\u MAX+1
而不是
$x=62574*62574,他们将能够成功地重现其余的疯狂。也许PHP技术已经有所改进,或者它是一个不同的PHP设置,但你的代码你认为这有什么作用?-1;这个答案无法理解OP的问题,更不用说解决它了。在高于PHP_INT_MAX的浮点值上调用
intval()
,将得到非常不正确的结果。对于
62574*62574
(2008年问题中使用的数字)来说,唯一的原因是,在更现代的PHP构建中,该数字低于
PHP_INT_MAX
——但出于同样的原因,提问者的原始代码在现代系统上运行良好,不需要对其进行更改。增加你的平方数,直到你最后被迫将$x变成一个浮点,你就会意识到这是错误的。代码显示了intval和sprintf之间的区别——通过sprintf提供了一个潜在的解决方案。对不起,SQL server是一个SQL server,而不是一个计算器。@GordonM,您是否从未在Delphi中使用ListBox对字符串进行过排序?@Namek鉴于Delphi的受欢迎程度,我怀疑在过去10年中是否有人使用过它。@Namek还有其他方法对字符串进行排序吗?;)@GordonM请检查Lazarus项目,你会惊讶于Pascal社区今天的表现:)GMP只适用于整数,而BC Math适用于浮点数。@Fleshgrinder不,BC Math支持任意精度的定点。浮点数是完全不同的。你完全正确,是的。上面的评论很快,我只想说
GMP==int&&BC==float
:)这不是一个很好的答案,因为这里没有例子。这是一个令人印象深刻的想法。添加你的答案的描述
<?php
    $x = gmp_strval(gmp_mul("62574","62574")); // $x="3915505476"
    $mod=gmp_strval(gmp_mod($x,"104659"));  //$mod="2968"

    echo "x : ".$x."<br>";
    echo "mod : ".$mod;

    /* Output:
        x : 3915505476
        mod : 2968
    */
?>
<?php
function add($int1,$int2){
    $int1 = str_pad($int1, strlen($int2), '0', STR_PAD_LEFT);
    $int2 = str_pad($int2, strlen($int1), '0', STR_PAD_LEFT);
    $carry = 0;
    $str = "";
    for($i=strlen($int1);$i>0;$i--){
        $var = $int1[$i-1] + $int2[$i-1] + $carry;
        $var = str_pad($var, 2, '0', STR_PAD_LEFT);
        $var = (string) $var;
        $carry = $var[0];
        $str = $str . $var[1];
    }
    $res = strrev($str.$carry);
    echo ltrim($res,"0");
}
add($int1,$int2);
?>