PHP « Очень большое число + поиск простых в диапазоне на PHP
Делал я это на php, простые числа я нахожу, но вот с их произведением у меня проблема... числа слишком большие, поэтому php выводит вместо произведения "INF" !!!
Разбиение на более мелкие участки не очень то помогает, их будет тысяч 10 или даже больше, может кто-нибудь портирует на другой язык, где можно работать с такими числами... Или подскажет как сделать это в php
Вот сам алгоритм:
/** * GeSHi (C) 2004 - 2007 Nigel McNie, 2007 - 2008 Benny Baumann * (http://qbnz.com/highlighter/ and http://geshi.org/) */ .php.geshi_code {font-family:monospace;} .php.geshi_code .imp {font-weight: bold; color: red;} .php.geshi_code .kw1 {color: #b1b100;} .php.geshi_code .kw2 {color: #000000; font-weight: bold;} .php.geshi_code .kw3 {color: #990000;} .php.geshi_code .co1 {color: #666666; font-style: italic;} .php.geshi_code .co2 {color: #666666; font-style: italic;} .php.geshi_code .co3 {color: #0000cc; font-style: italic;} .php.geshi_code .co4 {color: #009933; font-style: italic;} .php.geshi_code .coMULTI {color: #666666; font-style: italic;} .php.geshi_code .es0 {color: #000099; font-weight: bold;} .php.geshi_code .es1 {color: #000099; font-weight: bold;} .php.geshi_code .es2 {color: #660099; font-weight: bold;} .php.geshi_code .es3 {color: #660099; font-weight: bold;} .php.geshi_code .es4 {color: #006699; font-weight: bold;} .php.geshi_code .es5 {color: #006699; font-weight: bold; font-style: italic;} .php.geshi_code .es6 {color: #009933; font-weight: bold;} .php.geshi_code .es_h {color: #000099; font-weight: bold;} .php.geshi_code .br0 {color: #009900;} .php.geshi_code .sy0 {color: #339933;} .php.geshi_code .sy1 {color: #000000; font-weight: bold;} .php.geshi_code .st0 {color: #0000ff;} .php.geshi_code .st_h {color: #0000ff;} .php.geshi_code .nu0 {color: #cc66cc;} .php.geshi_code .nu8 {color: #208080;} .php.geshi_code .nu12 {color: #208080;} .php.geshi_code .nu19 {color:#800080;} .php.geshi_code .me1 {color: #004000;} .php.geshi_code .me2 {color: #004000;} .php.geshi_code .re0 {color: #000088;} .php.geshi_code span.xtra { display:block; }
<?php
//1000000-2000000
$p = 1; //Это произведение
for ($i = 1000000; $i<=2000000; $i++)
{
$no = 0; //Нужно для определения простоты числа ниже
if ($i%2 != 0) //Проверка на четность
{
$k = sqrt($i);
for ($d = 2; $d<=$k; $d++)
{
if ($i%$d == 0)
{
$no = 1;
break;
}
}
if ($no == 0)
{
$p = $p*$i;
}
}
}
echo $p;
?>
//Алгорит базируется на том, что верхняя граница перебора делителей
это квадратный корень из самого числа
Очень надеюсь, что здесь есть математики-программисты, которым это под силу (пожалуйста!)
1 ответов
Все, задача решилась на PHP, как ни странно. Во первых вы меня все простите, но я не правильно понял фразу по модулю 23, оказывается надо каждое число делить на 23 и брать остаток. Во вторых с таким подходом успешно разделился промежуток на 2, от миллиона до полтора, и от полтора до двух миллионов. Затем число смогла взять функция bcmul.
Всем большое спасибо!
Можно воспользоваться библиотекой для работы с числами произвольной точности: BC Math.
Почитайте про длинные числа. Вкратце: каждое число представляется в виде массива. Таким образом, если считать, что максимально возможным числом в PHP является 2^31, то массив таких чисел, фактически, это длинное число, записанное в системе с основанием 2^31. А дальше все просто реализуете простую библиотечку с переводом в длинные и обратно и четырьмя арифметическими действиями. Все арифметические действия производятся как в школе - в столбик.
Вот код на Java:
BigInteger p = new BigInteger("1");
mainloop: for (int i = 1000001; i<=2000000; i += 2) {
if (i % 10001 == 0) {
System.out.println(i + "\r");
}
int k = (int) Math.sqrt(i);
for (int d = 2; d <= k; d++) {
if (i % d == 0) {
continue mainloop;
}
}
p = p.multiply(new BigInteger(String.valueOf(i)));
}
String s = p.toString();
System.out.println(s.charAt(0) + "." + s.substring(1, 10) + "E+" + (s.length() - 1));
Выполняется примерно за 45 секунд на C2D@4300. В результате получается
В Python длинная арифметика включена в стандартные возможности. Для этого в синтаксисе есть суффикс "L" ([1])
На языке Python программа будет выглядеть приблизительно следующим образом:
from math import sqrt
def isPrime(N):
"Эта функция проверяет число на простоту"
limit = int(sqrt(N))
for d in xrange(3, limit+1, 2):
if N%d==0:
return False
return True
p = 1L
for n in xrange(1000001,2000001,2):
if isPrime(n):
p *= n
print p
Этот скрипт работал около 2-х минут и в результате получилось число, в котором 434340 знаков.