Чтобы использовать модульное возведение в степень, как вам потребуется при использовании теста перманентности Ферма с большими числами (100 000+), он требует некоторых очень больших вычислений.
Когда я умножаю два больших числа (например: 62574 и 62574), PHP, похоже, приводит результат в float. Получение значения модуля возвращает странные значения.
$x = 62574 * 62574; var_dump($x); // float(3915505476) ... correct var_dump($x % 104659); // int(-72945) ... wtf.
Есть ли способ заставить PHP правильно выполнить эти вычисления? Альтернативно, существует ли другой метод для определения значений модуля, которые будут работать для больших чисел?
По некоторым причинам в PHP есть две стандартные библиотеки, обрабатывающие произвольные номера длины / точности: BC Math и GMP . Я лично предпочитаю GMP, так как он свежее и имеет богатый API.
На основе GMP я применил класс Decimal2 для хранения и обработки валютных сумм (например, 100,25 долларов США). Там много модных расчетов без каких-либо проблем. Протестировано с очень большими числами.
использовать это
$num1 = "123456789012345678901234567890"; $num2 = "9876543210"; $r = mysql_query("Select @sum:=$num1 + $num2"); $sumR = mysql_fetch_row($r); $sum = $sumR[0];
вы взглянули на bcmod()
? php имеет проблемы с целыми числами более 2 ^ 31 – 1 на 32-битных платформах.
var_dump(bcmod("$x", '104659') ); // string(4) "2968"
Я предлагаю вам попробовать BigInteger . Если это не сработает, вы можете использовать SWIG, чтобы добавить код C / C ++ для вычислений большого целого и связать его с вашим кодом.
Я нашел другое решение, но число будет сохранено в виде строки. Как только вы вернете его к числовому, вы будете ограничены точностью базовой платформы. На 32-битной платформе наибольший int, который вы можете представить как тип int, составляет 2 147 483 647:
/** * @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"
$x = 62574 * 62574; // Cast to an integer $asInt = intval($x); var_dump($asInt); var_dump($asInt % 104659); // Use use sprintf to convert to integer (%d), which will casts to string $asIntStr = sprintf('%d', $x); var_dump($asIntStr); var_dump($asIntStr % 104659);
Я написал для вас очень маленький код, который, безусловно, будет работать в случае больших чисел –
<?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 */ ?>
Вам просто нужно использовать строки для хранения больших чисел и работать с ними, используя функции GMP в PHP.
Вы можете проверить некоторые хорошие функции GMP в официальном руководстве PHP здесь: http://php.net/manual/en/ref.gmp.php