PHP sprintf gives incorrect integer value

To use modular exponentiation as you would require when using the Fermat Primality Test with large numbers (100,000+), it calls for some very large calculations.

When I multiply two large numbers (eg: 62574 and 62574) PHP seems to cast the result to a float. Getting the modulus value of that returns strange values.

\$x = 62574 * 62574; var_dump(\$x);          // float(3915505476) ... correct var_dump(\$x % 104659); // int(-72945)  ... wtf.

Is there any way to make PHP perform these calculations properly? Alternatively, is there another method for finding modulus values that would work for large numbers?

Replay

For some reason, there are two standard libraries in PHP handling the arbitrary length/precision numbers: BC Math and GMP. I personally prefer GMP, as it's fresher and has richer API.

Based on GMP I've implemented Decimal2 class for storing and processing currency amounts (like USD 100.25). A lot of mod calculations there w/o any problems. Tested with very large numbers.

have you taken a look at bcmod()? php has issues with integers over 2^31 - 1 on 32 bit platforms.

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

use this

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

To put the large number into a variable (as a string) use sprintf:

\$big = 1000000000000000000;
\$myvar = sprintf('%.0f', \$big);

I suggest you try BigInteger. If that doesn't work out, you may use SWIG to add C/C++ code for the big integer calculations and link it into your code.

I wrote a very small code for you that will surely work in case of big numbers-

<?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
*/
?>

You simply have to use strings for storing big numbers and to operate on them use GMP functions in PHP.

You may check some good GMP functions in the official PHP manual here- http://php.net/manual/en/ref.gmp.php

I found another solution, but the number will be stored as a string. As soon as you cast it back to a numeric, you'll be restricted to the precision of the underlying platform. On a 32 bit platform, the largest int you can represent as an int type is 2,147,483,647:

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

// output: "123456789012345678911111111100"

Category: php Time: 2008-10-17 Views: 11
Tags: php bignum