0

When I was making a ftoa function by myself for my IoT product, I've got a weird problem with GCC on cygwin.

The program below should get zero. But the result is 1.000000!?

gcctest.c

#include <stdio.h>

void main()
{
    double f = 0.12;
    int d;
    f *= 10;    // f = 1.2
    d = (int)f; // d = 1
    f -= d;     // f = 0.2
    f *= 10;    // f = 2.0
    d = (int)f; // d should be 2
    f -= d;     // f should be 0.0
    printf("%lf\n", f);
}

if you try f = 0.11 or 0.13, you'll get zero correctly.

Since I doubt the "cast" operation at "d = (int)f", I tried a test program below.

gcctest2.c

#include <stdio.h>

int main()
{
    double f = 2.0;
    int d;
    d = (int)f;  // d = 2
    f -= d;      // f = 0.0
    printf("%lf\n", f);
}

With this case, the result is zero. It seems the procedure of "gcctest.c" holds some problem.

Is this known problem? Do you know how to avoid this case to get the correct result? I would appreciate it if I could get any helps.

The versions of gcc and cygwin are below.

$ gcc --version
gcc (GCC) 4.8.2
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ cygcheck -c cygwin
Cygwin Package Information
Package              Version        Status
cygwin               1.7.28-2       OK

Thanks, taro

Yoshino Taro
  • 101
  • 2
  • 1
    Print the value of `f` after each step using `"%.16f"` format and you will notice when the value of `f` starts to deviate from the analytical value. – R Sahu Sep 07 '16 at 15:12
  • Thanks for the quick responses guys. It seems this is well known problem. I don't want to leave it as it is, but there seems to be no way to avoid... – Yoshino Taro Sep 07 '16 at 15:37
  • @YoshinoTaro You could avoid it by using the `round` function before casting to `int`, e.g. `d = (int)round(f);`. Also, your `%lf` printf conversion specifier can be shortened to `%f` as the `l` is ignored in this case. – Ian Abbott Sep 07 '16 at 16:08
  • @IanAbbott I don't think `round` would be appropriate very often. You might try multiplying by (1 + epsilon) before truncating. – Mark Ransom Sep 07 '16 at 16:29
  • Thank you for the information! I'll try the way you guys teach me. I appreciate it very much. :) – Yoshino Taro Sep 07 '16 at 16:48

0 Answers0