By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
 428,591 Members | 629 Online + Ask a Question
Need help? Post your question and get tips & solutions from a community of 428,591 IT Pros & Developers. It's quick & easy.

# Correct precision with printf

 P: n/a I read the thread Floating point rounding error and I saw Richard Heathfield's description with several lines like: 0.1 = 1/2 = 0.5 - too large 0.01 = 1/4 = 0.25 - too large 0.001 = 1/8 = 0.125 - too large .... And I wanted to write such a program that output lines like that. My attempt is below, and I don't know how I should print the third column, with printf I either get too low precision or a lot of zeros after the first lines. Right now I just have %.20f in the format string, but I wonder how I can do it like Heathfield did and remove trailing zeroes. Otherwise I wonder if my program is a correct C program. Thanks! #include #include #include #include /* Examines the binary representation in the array to see if it is smaller or larger than value. Prints a new line containing the info and returns the result of the comparison. */ int examine(char *data, size_t length, double value) { size_t i; int num, den; double result; /* Shorten the length */ i = length; while (i-- && data[i] == 0) { length--; } assert(length != 0); num = 0; den = 1; printf("0."); for (i = 0; i < length; i++) { den *= 2; num *= 2; if (data[i] != 0) { putchar('1'); num++; } else putchar('0'); } result = (double)num/den; printf(" = %d/%d = %.20f", num, den, result); if (result == value) { printf(" - same\n"); return 0; } else if (result value) { printf(" - too large\n"); return 1; } else { printf(" - too small\n"); return -1; } } int main(int argc, char *argv[]) { char array = { 0 }; double val; int i; int cmp; if (argc < 2) return EXIT_FAILURE; val = strtod(argv, NULL); if (errno != 0) return EXIT_FAILURE; array = 1; for (i = 1; i < 17; i++) { cmp = examine(array, i, val); if (cmp == 0) return 0; else if (cmp < 1) { array[i] = 1; } else { array[i - 1] = 0; array[i] = 1; } } return EXIT_SUCCESS; } Jun 17 '07 #1
Share this Question
4 Replies

 P: n/a ba******@hushmail.com said: I read the thread Floating point rounding error and I saw Richard Heathfield's description with several lines like: 0.1 = 1/2 = 0.5 - too large 0.01 = 1/4 = 0.25 - too large 0.001 = 1/8 = 0.125 - too large ... And I wanted to write such a program that output lines like that. My attempt is below, Applause! For extra credit, make it work to an arbitrary precision. -- Richard Heathfield "Usenet is a strange place" - dmr 29/7/1999 http://www.cpax.org.uk email: rjh at the above domain, - www. Jun 17 '07 #2

 P: n/a I read the thread Floating point rounding error and I saw Richard Heathfield's description with several lines like: 0.1 = 1/2 = 0.5 - too large 0.01 = 1/4 = 0.25 - too large 0.001 = 1/8 = 0.125 - too large ... And I wanted to write such a program that output lines like that. My attempt is below, and I don't know how I should print the third column, with printf I either get too low precision or a lot of zeros after the first lines. Right now I just have %.20f in the format string, but I wonder how I can do it like Heathfield did and remove trailing zeroes. Otherwise I wonder if my program is a correct C program. Thanks! Use the %g conversion instead of %f. BTW, have you tried it with an argument <= 0 or >= 1? (And before returning EXIT_FAILURE I'd give the user a clue of why the program failed.) #include #include #include #include /* Examines the binary representation in the array to see if it is smaller or larger than value. Prints a new line containing the info and returns the result of the comparison. */ int examine(char *data, size_t length, double value) { size_t i; int num, den; double result; /* Shorten the length */ i = length; while (i-- && data[i] == 0) { length--; } assert(length != 0); num = 0; den = 1; printf("0."); for (i = 0; i < length; i++) { den *= 2; num *= 2; if (data[i] != 0) { putchar('1'); num++; } else putchar('0'); } result = (double)num/den; printf(" = %d/%d = %.20f", num, den, result); if (result == value) { printf(" - same\n"); return 0; } else if (result value) { printf(" - too large\n"); return 1; } else { printf(" - too small\n"); return -1; } } int main(int argc, char *argv[]) { char array = { 0 }; double val; int i; int cmp; if (argc < 2) return EXIT_FAILURE; val = strtod(argv, NULL); if (errno != 0) return EXIT_FAILURE; array = 1; for (i = 1; i < 17; i++) { cmp = examine(array, i, val); if (cmp == 0) return 0; else if (cmp < 1) { array[i] = 1; } else { array[i - 1] = 0; array[i] = 1; } } return EXIT_SUCCESS; } Jun 17 '07 #3

 P: n/a On Jun 17, 10:20 pm, "Army1987" = 1? (And before returning EXIT_FAILURE I'd give the user a clue of why the program failed.) Yeah, I knew of those two points, I should have said that. But thanks for pointing that out. Jun 18 '07 #4

 P: n/a ba******@hushmail.com writes: I read the thread Floating point rounding error and I saw Richard Heathfield's description with several lines like: 0.1 = 1/2 = 0.5 - too large 0.01 = 1/4 = 0.25 - too large 0.001 = 1/8 = 0.125 - too large ... And I wanted to write such a program that output lines like that. My attempt is below, and I don't know how I should print the third column, with printf I either get too low precision or a lot of zeros after the first lines. Right now I just have %.20f in the format string, but I wonder how I can do it like Heathfield did and remove trailing zeroes. %g has already been suggested, but %.*g (or %.*f) has not. This lets you pass the desired precision as a parameter to *printf function. The variable 'length' is a good first stab at the right value. -- Ben. Jun 18 '07 #5

### This discussion thread is closed

Replies have been disabled for this discussion. 