Большая арифметика

Novice

Новичок
Большая арифметика

Как получить все натуральные числа из интервала (заданы начало (А), конец (Б)) с шагом в 1.
Проблема в том что числа эти большие могут быть (14-16 цифр) и в Int они не влазят.
 

Novice

Новичок
Другие альтернативы есть чтобы без библиотеки?

Просто так получилось, что это все не факт что будет работать под *nix, а для винды написано

This extension is available on Windows platforms since PHP 5.1.0.

что тоже не факт :(
 

SiMM

Новичок
Проблема-то в чём? В банальной посимвольной обработке строки циклом?
 

Novice

Новичок
Угу, буду таки работать со строками.

спасибо.

-~{}~ 30.03.06 15:14:

Проблема-то в чём? В банальной посимвольной обработке строки циклом?
хех :) не так все просто...
Если например конец интервала 988 799 999, а начало
988 800 497
(чисел между ними 498)

Или я торможу...
 

SiMM

Новичок
hint: строки можно сравнивать. И циклы для этого не нужны.
 

Novice

Новичок
Автор оригинала: SiMM
hint: строки можно сравнивать. И циклы для этого не нужны.
уважаемый, нужен хинт номер 2 :)
про сравнение строк знаю, но как прикрутить его сюда?
 

SiMM

Новичок
PHP:
$start = '988799999';
$end = '988800497';
$inc = array(1,2,3,4,5,6,7,8,9,0);
for ($n = $start; $n <= $end; ) { // вот и прикрутили
  echo $n."\n";
  for ($i = strlen($n); $i--;)
    if ($n[$i] = $inc[$n[$i]]) break;
}
Особые случаи рассматривай самостоятельно - это только пример.
 

tigerman

Новичок
Автор оригинала: SiMM
PHP:
$start = '988799999';
$end = '988800497';
$inc = array(1,2,3,4,5,6,7,8,9,0);
for ($n = $start; $n <= $end;  ) { // вот и прикрутили
  echo $n."\n";
  for ($i = strlen($n); $i--; )
    if ($n[$i] = $inc[$n[$i]]) break;
}
Особые случаи рассматривай самостоятельно - это только пример.
Этот код работает и в таком виде:
PHP:
$start = '988799999';
$end = '988800497';
for ($n = $start; $n <= $end; $n++)
{
  echo $n."\n";
}
а попробуй запустить свой пример для таких значений к примеру:
PHP:
$start = '10000000000000000000000';
$end = '10000000000000000000011';
?!
 

SiMM

Новичок
> а попробуй запустить свой пример для таких значений
Хм... "клинит"
Интересно, почему?

-~{}~ 31.03.06 10:12:

Лечится использованием [m]strcmp[/m]

-~{}~ 31.03.06 10:15:

[m]language.operators.comparison[/m]
В случае, если вы сравниваете две числовые строки, они сравниваются как целые числа.
 

Novice

Новичок
К чему пришел я:

PHP:
$a = 1234567891234567;
$b = 1234567891234577;

$c = sprintf("%.0f", $b - $a);
for ($i = 0; $i <= $c; $i++) {
	$d[] = sprintf("%.0f", $a+$i);
}
print_r($d);
 

SiMM

Новичок
PHP:
$a = 12345678901234560;
$b = 12345678901234569;
/*
Array
(
    [0] => 12345678901234560
    [1] => 12345678901234560
    [2] => 12345678901234562
    [3] => 12345678901234565
    [4] => 12345678901234565
    [5] => 12345678901234565
    [6] => 12345678901234567
    [7] => 12345678901234567
    [8] => 12345678901234567
)
*/
 

Novice

Новичок
Автор оригинала: SiMM
PHP:
$a = 12345678901234560;
$b = 12345678901234569;
Хм... "клинит"
Интересно, почему? :)

пробовал менять precision, но видимо не в этом дело...

-~{}~ 31.03.06 14:28:

вообще-то для 16-значных мой метод работает, и этого в принципе достаточно (речь идет о вычислении последовательности 16-значных серийных номеров карт)

но почему он не работает для бОльших чисел?...
 

Novice

Новичок
Вот вспомнил 3-й класс :)
PHP:
function str_to_array ($str) 
{
	$c = strlen($str);
	$array = array();
	for ($i = 0; $i < $c; $i++) {
		$array[] = (int)$str{$i};
	}
	return $array;
}

$a = "12345678901234560"; 
$b = "12345678901234569"; 

$max = strlen($a);

$a = str_to_array($a);
$b = str_to_array($b);

while ($a != $b)
{
    $a[$max-1] = $a[$max-1]+1;
    for($i = $max-1; $i > 0; $i--) {
        if($a[$i] > 9)
        {
            $a[$i] = 0;
            $a[$i-1] = $a[$i-1]+1;
        }
    }
    $d[] = implode("", $a);
}

print_R($d);
ЗЫ: сильно не тестировал, но вроде работает

ЗЗЫ: преобразование строки в массив посчитал нужным, так как если в сложении разрядов получаеться 10 - он отсекает младший байт и дает 1 (типа один симаол)
 
Сверху