0

i want to extract the decimal part of a float variable by substracting the whole part, the thing is i get a wrong value

#include<stdio.h>
int main(){
    int k ;
    float a=12.36,i;
    k = (int)a;
    i = a - k ;
    i*=10;
    printf("%f",i);
    return 0;
}

well, the output is 3.599997 not 3.6 , is there a way to solve this ? edit : i know it's because of the binary conversion, i m asking if there is a solution to get the right result, not the cause of it. ty for the replies anw. edit 2 : sadly it's not a matter of display, i want the stored value to be 3.6 ( in this case) because i need it in other calculations.

Anox row
  • 1
  • 1
  • Aside: why are you using `float`? Never use `float` without a clear reason why you cannot use `double`, the natural floating point type in C. – Weather Vane Nov 05 '22 at 15:03
  • If it is just a matter of presentation `%.1f`. The issue is that `float` is a _binary floating-point_ representation. To get expected decimal results, you would need a _decimal floating-point_ representation, which is not native to the FPU, so slow. Neither 12.36 not 3.6 are precisely representable in binary FP, it is not "wrong", rather a matter of necessarily finite precision, not coincident with decimal. – Clifford Nov 05 '22 at 15:26
  • @Anox row, "3.599997" is the better answer for `i`. Try `float a=12.36; printf("%.30f\n", a);` to see why `a` is not `12.36`. – chux - Reinstate Monica Nov 05 '22 at 19:12
  • @WeatherVane note that you get a similar issue when using a `double`. the decimal expansion of the nearest IEEE binary64 to 12.36 is 12.3599999999999994315658113919198513031005859375. – Sam Mason Nov 05 '22 at 21:25
  • @SamMason it was an aside. You don't use `short` instead of `int` just because the range is small without a good reason, although here there is precision too. – Weather Vane Nov 05 '22 at 21:29
  • 1
    @WeatherVane yup, not disagreeing with your suggestion to use `double`. just that floats are binary rather than decimal. note to OP, modern x86-64 CPUs can retire 2 `float`s or `double` instructions per clock (e.g. search for VADDSS / VADDSD / VMULSD in https://uops.info/) meaning they're just as fast as each other for basic operations. so the only practical difference would be when you start needing to move large arrays around. – Sam Mason Nov 05 '22 at 21:39
  • @Anoxrow You say you you know about the binary conversion, but then you say you "want the stored value to be 3.6". But in binary floating point *there is no such value as 3.6*. Try saying `i = 3.6;` and then printing it; you'll get the same result. – Steve Summit Nov 06 '22 at 13:33
  • The right solution to this problem depends on what you are trying to do. But there's no way to store a value of exactly 0.36 or 3.6 in a binary floating-point variable. If you're working with currency (like dollars and cents), sometimes it's worthwhile to work with integer (or long integer) cents, rather than floating-point dollars. Otherwise, the solution is probably to understand the later part of your code that's failing when `i` is 3.5999999, and fix that code to be a bit more tolerant. – Steve Summit Nov 06 '22 at 13:37

0 Answers0