Listing 1: An implementation of Newton's square root algorithm.
/* An implementation of Newton's square root algorithm. */ /* Try compiling it with -foptimize-sibling-calls and take the square root of (say) 101, then try the same again, without the compiler optimization in place. */ #include <stdio.h> #include <stdlib.h> #include <math.h> #define ACCURACY 0.0000001 float newton (int); float find_root (float, float); int close_enough (float, float); int calls; int main (void) { int input = 0; calls = 1; printf ("Enter a number: "); scanf ("%d", &input); printf ("The square root of %d is approx. %f.\n", input, newton (input)); printf ("Function calls required: %d\n", calls); return 0; } float newton (int input) { calls++; /* This tail call cannot be optimized, because find_root requires a larger argument space than its caller: */ return find_root ((float) input, 1); } float find_root (float input, float guess) { if (close_enough (input / guess, guess)) return guess; else { calls++; /* This tail call can and will be optimized: */ return find_root (input, (guess + input / guess) / 2); } } int close_enough (float a, float b) { return (fabs (a - b) < ACCURACY); }