//========================================================================= #define PROGRAMMER "SOLUTIONS, NoFrills" #define PROG_CODE "soln" #define COURSE "ECE-1021" #define YEAR (2003) #define TERM "Fall" #define SECTION (0) #define ASSIGNMENT "HW #3A" #define REVISION (0) #define TITLE "Resistor Color Code" #define SUBTITLE "Problem 5.4" #define EMAIL "wbahn@eas.uccs.edu" #define FILENAME "03a0soln.c" //========================================================================= // PROBLEM: // // Write a function that prints the color codes for a resistor given the // resistance and the tolerance. // // SOLUTION: // // As given in the auxillary information on the course website, the codes // fall into three types - 3 band, 4 band, and 5 band - based on the // tolerance. // // Tolerance = 20% => 3 Band (Value, Value, Multiplier) // Tolerance = 10% => 4 Band (Value, Value, Multiplier, Silver) // Tolerance = 5% => 4 Band (Value, Value, Multiplier, Gold) // Tolerance = 2% => 5 Band (Value, Value, Value, Multiplier, Red) // Tolerance = 1% => 5 Band (Value, Value, Value, Multiplier, Brown) // // No other tolerances are valid. // // We know that the multiplier has to be between 0.01 and 1e9. If the // resistance value not less than than 100 (1000 for 5-band resistors) // then we can divide by ten and up the multiplier. If, upon reaching // a multiplier of 1e9 the value is still not less than 100 (or 1000) // we know the value can't be represented. // // On the other end, if the value is less than 10 (100 for 5-band) then // we cam multiply by ten until it is, subject to the constraint that // we can only do this twice. If the value at that time is less than one. // the value can't be represented. // // Once we have the resistance scaled properly, we can then round the // value to the nearest integer and use modulo ten division to pick off // the ones, tens, and (for 5-band) the hundreds digits in turn. // // PSEUDOCODE (fleshed out from code in 03a0soln.txt) // 1) TASK: Get valid tolerance from user. // 1.1) SET: tol to invalid value // 1.2) WHILE: (tol is invalid) // 1.2.1) GET: tol from user // 2) TASK: Get resistance value from user. // 2.1) SET: rmmx to largest representable resistance // 2.2) DO: // 2.2.1) GET: r from user // 2.2.2) WHILE: (r > rmax) OR (r < 0.0) // 3) TASK: Determine the number of color bands. // 3.1) IF: (tol = 20) // 3.1.1) SET: bands = 3 // 3.2) IF: (tol = 10) OR (tol = 5) // 3.2.1) SET: bands = 4 // 3.3) IF: (tol = 2) OR (tol = 1) // 3.3.1) SET: bands = 5 // 4) TASK: Scale the resistance value properly and determine multiplier // 4.1) TASK: Scale value to rr.rrrr.... // 4.1.1) SET: m = 0 // 4.1.2) TASK: Scale value up if needed (r < 10.0) // 4.1.2.1) WHILE: (r < 10.0) // 4.1.2.1.1) SET: r *= 10 // 4.1.2.1.2) SET: m-- // 4.1.3) TASK: Scale value down if needed (r >= 100.0) // 4.1.3.1) WHILE: (r >= 100.0) // 4.1.3.1.1) SET: r /= 10 // 4.1.3.1.2) SET: m++ // 4.2) TASK: Scale value to rrr.rrr.... if 5 band // 4.2.1) IF: (bands = 5) // 4.2.1.1) SET: r *= 10 // 4.2.1.2) SET: m-- // 4.3) TASK: Impose constrant of minimum multiplier = -2 // 4.3.1) WHILE: (m < -2) // 4.3.1.1) SET: r /= 10 // 4.3.1.2) SET: m++ // 5) TASK: Round the scaled resistance to the nearest integer. // 5.1) SET: int_r = (int) (r + 0.5) // 6) TASK: Determine the digit values for the value bands. // 6.1) TASK: Determine how many digits to pick off int_r // 6.1.2) IF: (bands < 5) // 6.1.2.1) SET: i = 1 (two digits) // 6.1.3) ELSE: // 6.1.3.1) SET: i = 2 (three digits) // 6.2) TASK: Pick off the appropriate digits // 6.2.1) LOOP: // 6.2.1.1) SET: digit[i] = int_r % 10 // 6.2.1.2) SET: int_r /= 10 (integer division) // 6.2.1.3) SET: i-- // 6.2.1.4) WHILE: (i > 0) // 7) TASK: Print out the band colors for the resistor. // 7.1) TASK: Print out the first value band // 7.1.1) OUT: Color corresponding to digit[0] // 7.2) TASK: Print out the first value band // 7.2.1) OUT: Color corresponding to digit[1] // 7.3) TASK: Print out the first value band // 7.3.1) IF: (bands = 5) // 7.3.1.1) OUT: Color corresponding to digit[2] // 7.4) TASK: Print out multiplier band // 7.4.1) OUT: Color corresponding to m // 7.4) TASK: Print out tolerance band // 7.4.1) OUT: Color corresponding to tol // The code below represents a minor reorganization of the tasks so as // to keep main() very clean and to meet the explicit requirements of // the problem that there be a call to the function color_band(). //== INCLUDE FILES ======================================================== #include // printf(), scanf() //== FUNCTION PROTOTYPES ================================================== void PrintHeader(void); void color_band(double r, int tol); int Bands(int tol); double MaxRes(int tol); int IsResistanceLegal(double r, int bands); void PrintValueBand(int digit); void PrintMultiplierBand(int digit); void PrintToleranceBand(int digit); //== MAIN FUNCTION ======================================================== int main(void) { int tol; // tolerance {1,2,5,10,21} double r; // resistance 0.01 < r < rmax PrintHeader(); printf("\n"); // Print a blank line // 1) TASK: Get valid tolerance from user. do { printf("Enter the resistor percent tolerance {20, 10, 5, 2, 1}: "); scanf("%i", &tol); } while(0 == Bands(tol) ); // 2) TASK: Get resistance value from user. do { printf("Enter the resistor value (0 < r < %2e): ", MaxRes(tol)); scanf("%lf", &r); } while ( !IsResistanceLegal(r, tol) ); // 3) TASK: Print out the color bands for the resistor. color_band(r, tol); 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; } int Bands(int tol) { // This function returns the number of bands in the color code - and // hence a TRUE logic value - if the tolerance is a valid value and // returns 0 - and hence FALSE - otherwise. int bands; switch(tol) { case 20: bands = 3; break; case 10: case 5: bands = 4; break; case 2: case 1: bands = 5; break; default: bands = 0; } return(bands); } double MaxRes(int tol) { switch(Bands(tol)) { case 3: case 4: return(99e9); case 5: return(999e9); } return(-1); // Should never reach this point (unless tol is invalid) } int IsResistanceLegal(double r, int tol) { return( (r <= MaxRes(tol)) && (r >0.0) ); } void PrintValueBand(int digit) { switch(digit) { case 0: printf("BLACK"); break; case 1: printf("BROWN"); break; case 2: printf("RED"); break; case 3: printf("ORANGE"); break; case 4: printf("YELLOW"); break; case 5: printf("GREEN"); break; case 6: printf("BLUE"); break; case 7: printf("VIOLET"); break; case 8: printf("GRAY"); break; case 9: printf("WHITE"); break; } return; } void color_band(double r, int tol) { int bands; // number of color bands int int_r; // integer resistance - one digit per value band int digit[3]; // the split out digits - digit[0] is 1st band int i; // dummy variable for loops int m; // multiplier exponent // 1) TASK: Determine number of color bands. switch(tol) { case 20: bands = 3; break; case 10: case 5: bands = 4; break; case 2: case 1: bands = 5; break; } // 2) TASK: Scale the resistance value properly and determine multiplier // 2.1) TASK: Scale value to rr.rrrr.... m = 0; // 2.1.2) TASK: Scale value up if needed (r < 10.0) while( r < 10.0) { r *= 10.0; m--; } // 2.1.3) TASK: Scale value down if needed (r >= 100.0) while( r >= 100.0) { r /= 10.0; m++; } // 2.2) TASK: Scale value to rrr.rrr.... if 5 band if(5 == bands) { r *= 10.0; m--; } // 2.3) TASK: Impose constrant of minimum multiplier = -2 while( m < -2 ) { r /= 10.0; m++; } // 3) TASK: Round the scaled resistance to the nearest integer. int_r = (int) (r + 0.5); for( i = (bands < 5)? 1 : 2; i >= 0; i-- ) { digit[i] = int_r % 10; int_r /= 10; // intentional integer division } // 4) TASK: Print out the band colors for the resistor. printf("\n"); printf("The color bands for the specified resistor are:\n"); printf("\n"); printf("1st Value .... "); PrintValueBand(digit[0]); printf("\n"); printf("2nd Value .... "); PrintValueBand(digit[1]); printf("\n"); if(5 == bands) { printf("3rd Value .... "); PrintValueBand(digit[2]); printf("\n"); } printf("Multiplier ... "); PrintMultiplierBand(m); printf("\n"); printf("Tolerance .... "); PrintToleranceBand(tol); printf("\n"); return; } void PrintMultiplierBand(int digit) { switch(digit) { case -2: printf("GOLD"); break; case -1: printf("SILVER"); break; default: PrintValueBand(digit); } return; } void PrintToleranceBand(int digit) { switch(digit) { case 20: printf("NONE"); break; case 10: printf("SILVER"); break; case 5: printf("GOLD"); break; case 2: case 1: PrintValueBand(digit); break; } return; }