Thomas Blanquet Thomas Blanquet - 24 days ago 7
C Question

Decompose decimal part of a double



I need to decompose a decimal part of a number in single digits, but I need to get the most obvious representation. Here is my code, to be clearer :


#include <stdio.h>

void main(){
double value = 0.123;
int decim_tab[6];
int decimal;
int i;

for (i = 0; i < 6; ++i) {
value *= 10;
decimal = (int)value;
decim_tab[i] = decimal;
value -= decimal;
}
for (i = 0; i < 6; ++i)
print("%d\n", decim_tab[i]);
}


The output I need is :


1
2
3
0
0
0


But I get :


1
2
2
9
9
9


EDIT

A solution I found is to add a small delta to the value in order to force the shortest representation :

#include <stdio.h>

void main(){
double value = 0.123;
int decim_tab[6];
int decimal;
int i;

value += 0.000000001
for (i = 0; i < 6; ++i) {
value *= 10;
decimal = (int)value;
decim_tab[i] = decimal;
value -= decimal;
}
for (i = 0; i < 6; ++i)
print("%d\n", decim_tab[i]);
}


I would be happy to find a better way, any suggestions ?

Answer

The reason you get unexpected output is that decimal fractions cannot always be exactly represented using (most common) base two floating point numbers. Using printf("%.20f", value); after your assignment of value you will see that the value 0.123 is actually being stored as 0.12299..., which is why you receive that output.

If you only need to print out six digits, you can use string formatting of floating point numbers:

#include <stdio.h>
#include <stdlib.h>

void main(){
    double value = 0.123;
    char *s = malloc(9);

    sprintf(s++, "%.6f", value);
    while(*s++){
        putchar(*s);
        putchar('\n');
    }
}
Comments