Correct precision with printf



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 <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <assert.h>

/* 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[17] = { 0 };
double val;
int i;
int cmp;

if (argc < 2)
return EXIT_FAILURE;

val = strtod(argv[1], NULL);
if (errno != 0)
return EXIT_FAILURE;

array[0] = 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;
}

.



Relevant Pages

  • Re: [RFC] New kernel-message logging API
    ... return buf; ... static char* put_dec(char *buf, unsigned long long num) ... static int skip_atoi ...
    (Linux-Kernel)
  • Re: Ex 7-5
    ... void clearStack; ... I don't interpret the suggestion to rewrite to use scanf ... // Tondo and Gimpel has the next declaration wrongly an int ... double num; ...
    (comp.lang.c)
  • Reverse Numbers
    ... I want them displayed in reverse order in the status bar. ... public void actionPerformed(ActionEvent actionEvent) ... public int qualityPoints(int num) ...
    (comp.lang.java.help)
  • Re: Ex 7-5
    ... int getop; ... double num; ... allowed me to get whatever stack values I wanted in the first ... void clearStack; ...
    (comp.lang.c)
  • Re: sob..Someone can help me????plsss
    ... main returns an int. ... float num1,num2,num3,num4; ... Note that scanf doesn't touch num if ... use scanf() unless there is no better choice. ...
    (comp.lang.c)