C: f> 0 против Perl: $ f> 0? - PullRequest
       18

C: f> 0 против Perl: $ f> 0?

1 голос
/ 30 марта 2011

Этот код C отображает числа Фибоначчи:

#include <stdio.h>
int main(){
   for (long long int t, i=1, p=1, f=2; f>0 ; i++, t=f, f+=p, p=t)
      printf("%lli: %lli\n", i, f); 
   }

Как и положено, он останавливается без необходимости жесткого кодирования числа итераций.

Код в Perl пытается использовать ту же технику:

my $t;
my $p=1;
my $f=2;
for ($i=1; $f>0; $t=$f, $f+=$p, $p=$t, $i++){
   printf("%i: %i\n", $i, $f);
   if ($i>50){exit;}
   }

Но он не останавливается, как ожидалось, в тот момент, когда значение переполняется на 45, а не на 51, когда начинается дополнительная проверка.

44: 1836311903
45: -1323752223
46: -1
47: -1
48: -1
49: -1
50: -1
51: -1

Что делает Perlиначе что вызывает это?

Ответы [ 5 ]

5 голосов
/ 30 марта 2011

Perl использует произвольные типы, переключаясь между беззнаковыми и знаковыми целыми числами и с плавающей точкой по мере необходимости. printf, однако, принудительно преобразует произвольный тип в целое число. Попробуйте использовать% s вместо:

my $t;
my $p=1;
my $f=2;
for ($i=1; $f>0; $t=$f, $f+=$p, $p=$t, $i++){
   printf("%i: %s\n", $i, $f);
   if ($i>50){exit;}
}

Большое отрицательное число фактически сохраняется в perl как целое число без знака; -1 слишком большие числа с плавающей запятой, усеченные до максимального целого числа без знака, но затем обработанные как подписанные% i.

3 голосов
/ 30 марта 2011

Ваш код целого числа со знаком C переполняется с большого числа на отрицательное и останавливается.Использование в Perl плавающей pt math позволяет ему проходить больше итераций с пониженной точностью, и я не думаю, что это обернется, когда число станет действительно большим.

2 голосов
/ 30 марта 2011

Ваш код c фактически завершается из-за плохой практики программирования.Вы полагаетесь на f как long long int, который имеет верхний предел 9,22337204 × 10 ^ 18.Когда вы возвращаетесь к 91-й итерации, f становится 1.22001604 × 10 ^ 19, что переполняется и становится отрицательным.

Код Perl продолжается весело, но, как вы должны заметить, в конце концов вы распечатаетепоследовательность -1 s, которая должна указывать на то, что ваш код неверен.

Если бы у вас не было ограничений на целочисленный размер, ваш код c продолжался бы вечно, что, вероятно, не то, чтоты хочешь.Для бесконечных последовательностей, таких как последовательность Фибоначчи, вы хотите иметь условие остановки.

1 голос
/ 30 марта 2011

Вы используете 32-разрядные целые числа в Perl и большие целые числа в C. 32-разрядных недостаточно для хранения этих чисел. Вы можете перестроить свой Perl для использования 64-битных целых чисел или позволить Perl использовать числа с плавающим указателем (53-битные целые без потерь), как предложено ysth.

1 голос
/ 30 марта 2011

Возможно, для кода Perl по умолчанию используется арифметика с плавающей точкой.Кажется, это то, что указывает этот .Попробуйте добавить туда use integer;.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...