Завершение цикла C при максимальной аппаратный предел достигнут


В ответ на такой вопрос с: ф>0 против на Perl: $ф>0?, использование переполнения, чтобы завершить цикл называется "плохим стилем программирования". Перефразировал:

Ваш код на C-это фактически не выходя из-за плохой практикой программирования. Ты опираясь на привирать быть длинный инт, которая имеет верхний предел 9.22337204 × 10^18. Когда вы петлю вокруг 93-й итерации привирать будет 1.22001604 × 10^19, который переполняется и становится отрицательно.

Практически такой же код:

cat >fib.c <<EOF
#include <stdio.h>
int main(){
   for (long long int temp, i=1, prev=0, fib=1; fib>0 ; i++, temp=fib, fib+=prev, prev=temp)
      printf("%lli: %lli\n", i, fib); 
   }
EOF
gcc -std=c99 -ofib fib.c
./fib

Код был предназначен, чтобы быть один раз выбрасывать "программу", которая подтверждается использованием одной переменной букву названия в оригинальной версии. Использование переполнения указывает привирать став отменяет используется для завершения цикла.

Не зная заранее, какое максимальное число повторений аппаратная архитектура может справиться, что бы хорошо "практику программирования" для завершения цикла, зная, что длинный интервал ограничено, но желающих так много значения, как это возможно?



Комментарии
2 ответа

Использовать неподписанные, а не подписал, потому что сразу возникает переполнение эффект неопределен.
В то время как с неподписанным нет переполнения, но по модулю арифметических операций плюс он создает дополнительную ценность.

cat >fib2.c <<EOF
// Fibinocci numbers
#include <stdio.h>
int main(){
for (unsigned long long ii=1, fib=1, prev=0, temp;
fib>=prev; // Wrap indicates max value per implementation
ii++, temp=fib, fib+=prev, prev=temp)
printf("%llu: %llu\n", ii, fib);
}
EOF
gcc -std=c99 -ofib2 fib2.c
./fib2

7
ответ дан 6 апреля 2011 в 05:04 Источник Поделиться

Хорошая практика программирования, зная, что ваш цикл будет выйти. В вашем случае, при условие выхода является привирать <= 0. Думать об алгоритме, является привирать не будет неположительным?

Вы хотите, чтобы выйти после какое-то условие. Для последовательностей, как это вы обычно завершает цикл либо после определенного количества итераций (т. е. "создавать первые 50 чисел Фибоначчи") или когда ваши ценности вам достаточно большой (т. е. "создания всех чисел Фибоначчи, меньших 50000").

Если вы действительно хотите создать бесконечное число значений в бесконечной последовательности, вы должны взять свои типы переменных во внимание. Очевидно, что вы не использовать логическое значение, ведь ее ассортимент маленький. Кроме того, даже длинный инт не достаточно, поскольку это конечное, ограниченное. Если вы хотите выйти за пределы диапазона типы переменных, вам нужно прийти с пользовательских переменных или найти библиотеку, которая обеспечивает эту функциональность. Для C, вы, вероятно, использовать ГМП.

В этом случае ваш цикл только выходит из-за присущих им ограничений программного обеспечения. Это не дает те же результаты на разных платформах, и это даст те же результаты для различных реализаций с разными языками (как вы видели, когда вы пытались код то же самое на Perl). Это будет считаться плохой практикой программирования, так как результаты довольно неопределенное и привести к путанице.

4
ответ дан 1 апреля 2011 в 03:04 Источник Поделиться