patterncMinor
Terminating a C loop when maximum hardware limit reached
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
which has an upper limit of 9.22337204
× 10^18. When you loop around to the
93rd iteration
10^19, which overflows and becomes
negative.
Substantially the same code:
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
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
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
./fibThe 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.
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
./fib2Code 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
./fib2Context
StackExchange Code Review Q#1607, answer score: 7
Revisions (0)
No revisions yet.