HiveBrain v1.2.0
Get Started
← Back to all entries
patterncMinor

Terminating a C loop when maximum hardware limit reached

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
maximumlimitloophardwareterminatingreachedwhen

Problem

In response to the SO question C: f>0 vs Perl: $f>0?, the use of overflow to terminate the loop is referred to as "poor programming practice". Paraphrased:


Your c code is actually exiting because of
poor programming practice. You're
relying on fib being a long long int,
which has an upper limit of 9.22337204
× 10^18. When you loop around to the
93rd iteration fib becomes 1.22001604 ×
10^19, which overflows and becomes
negative.

Substantially the same code:

cat >fib.c 
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


The code was intended to be a one time "throw-away" program which was evidenced by the use of single letter variable names in the original version. The use of the overflow being indicated by fib becoming negate was used to terminate the loop.

Without knowing in advance what the maximum number of iterations the hardware architecture could handle what would be good "programming practice" to terminate the loop knowing that long long int is limited yet desiring as many values as possible?

Solution

Use unsigned rather than signed because once there is overflow the effect is undefined.
Whereas with unsigned there is no overflow but modulo arithmetic plus it produces an additional value.

cat >fib2.c 
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

Code Snippets

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

Context

StackExchange Code Review Q#1607, answer score: 7

Revisions (0)

No revisions yet.