//========================================================================= #define PROGRAMMER "SOLUTIONS, NoFrills" #define PROG_CODE "soln" #define COURSE "ECE-1021" #define YEAR (2004) #define TERM "Spring" #define SECTION (0) #define ASSIGNMENT "HW #4B" #define REVISION (0) #define TITLE "Mystery Algorithm" #define SUBTITLE "Function: Square Root - debugged" #define EMAIL "ece1021@eas.uccs.edu" #define FILENAME "04b0soln.c" //========================================================================= // PROBLEM // // The pseudocode for the original version of this algorithm had two // bugs: // // 1) If asked to calculate the square root of zero, the program went into // an infinite loop. Although the square root of zero is well-defined, // namely zero, the program keeps attempting to produce significant // digits until it has generated the requested number. But, according // the the normal rules for counting sig figs, zero has no sig figs. // // The solution to this bug is to trap the value '0' and treat it as // an explicit case. // // 2) If asked to a calculate the square root such that the result has // M sig figs to the left of the decimal point and the number of // sig figs requested is less than M, then the output will only print // the significant digits and stop when it should print trailing zeros // until it reaches the decimal point. // // The solution is to use the value of 'j' after the algorithm has // completed to print out an additional 'j' zeros. If 'j' is negative // the the decimal point has already been printed and this rule // does not apply. // PSEUDOCODE // // 1) TASK: Get a number and number of sig figs from the user // 2) TASK: Print the output header // 3) TASK: Trap an input value of zero and output zero // 4) TASK: Initialize working value // 5) TASK: Initialize certain variables based on size of input // 6) TASK: Generate output one digit at a time // 6A) TASK: Determine next digit // 6B) TASK: Update Partial Results (z and s) // 6C) TASK: Output digit if significant and/or needed placeholder // 6D) TASK: Output decimal point if appropriate // 7) TASK: Generate trailing zeros if needed // RUNTIME RESULTS // // INPUT SIG OUTPUT // 2.0 3 1.41 // 20000 3 141 // 0.002 3 0.0447 // 100 3 10.0 // 90000 3 300. // // The function appears to be the square root function. //== INCLUDE FILES ======================================================== #include // printf() //== FUNCTION PROTOTYPES ================================================== void PrintHeader(void); //== MAIN FUNCTION ======================================================== int main(void) { double x; // value entered by user int sig; // number of significant figures to print double y; // working value double z; int j; double s; int k; double d; int n; PrintHeader(); printf("\n"); // Print a blank line // 1) TASK: Get a number and number of sig figs from the user printf("Enter a non-negative floating point value: "); scanf("%lf", &x); printf("Enter number of significant digits to produce: "); scanf("%i", &sig); // 2) TASK: Print the output header printf("The output value is "); // 3) TASK: Trap an input value of zero and output zero // -- NEW CODE --- if(0==x) // equality on floating point intended { printf("0"); // Print first sig fig // -- NEW CODE, but optional --- if(1 < sig) { printf("."); while(1 < sig--) printf("0"); // Print additional sig figs } // ----------------------------- sig = 0; // Force remainder of code to exit without any output // Could also simply execute a return(0) to end here. } // --------------- // 4) TASK: Initialize working value y = 5.0*x; // 5) TASK: Initialize certain variables based on size of input z = 1.0; j = 0; while( (y - 100.0*z) >= 0.0 ) { z = 100.0*z; j++; } // 6) TASK: Generate output one digit at a time s = 0.0; k = 0; while( k < sig ) { n = 0; do { d = (100.0*s + 5.0*(2*n + 1))*z; y = y - d; n = n + 1; } while(y >= 0); // UNTIL ( y < 0 ) y = y + d; n--; z = z / 100.0; s = 10*s + n; if( k > 0) { k++; printf("%i", n); } else { if( n > 0) { k++; printf("%i", n); } else { if( j < 0 ) printf("%i", n); } } if( 0 == j ) printf("."); j--; } // -- NEW CODE --- while(j-- >= 0) // Output required trailing zeros. printf("0"); // --------------- return(0); } //== SUPPORT FUNCTIONS ==================================================== void PrintHeader(void) { printf("========================================" "=======================================\n"); printf("Course....... %s-%i (%s %i)\n", COURSE, SECTION, TERM, YEAR); printf("Programmer... %s (%s)\n", PROGRAMMER, PROG_CODE); printf("Assignment... %s (Rev %i) (Source Code in %s)\n", ASSIGNMENT, REVISION, FILENAME); printf("Description.. %s\n", TITLE); printf(" %s\n", SUBTITLE); printf("========================================" "=======================================\n"); return; }