B
banansol
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 == 0) {
length--;
}
assert(length != 0);
num = 0;
den = 1;
printf("0.");
for (i = 0; i < length; i++) {
den *= 2;
num *= 2;
if (data != 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 = 1;
}
else {
array[i - 1] = 0;
array = 1;
}
}
return EXIT_SUCCESS;
}
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 == 0) {
length--;
}
assert(length != 0);
num = 0;
den = 1;
printf("0.");
for (i = 0; i < length; i++) {
den *= 2;
num *= 2;
if (data != 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 = 1;
}
else {
array[i - 1] = 0;
array = 1;
}
}
return EXIT_SUCCESS;
}