0

I want to be able print out a double precision number s.t it is identical to the original decimal number in C language.

char buf[1000];
double d = ______;

For a double, I would do

snprintf(buf, sizeof(buf), "%.17g", .1);

But it will print out on doing : printf("%s", buf);

0.10000000000000001

There is a last 1 as a rounding error

It prints out the closest decimal representation double precision value if you try to represent .1 . Casting .1 to double, you get a rounding error. Casting back to decimal, you will get another rounding error.

Is there a way to fix this?

surajs1n
  • 1,493
  • 6
  • 23
  • 34
Crowning
  • 167
  • 1
  • 2
  • 10
  • 1
    It is a little unclear whether you are asking about limitations of the *IEEE-754 double-precision floating point format* or if you are asking how to work around it. Please clarify. – David C. Rankin Nov 15 '15 at 07:14
  • @DavidC.Rankin Could you please explain me both the limitations of the IEEE-754 double-precision floating point format and how to fix this mentioned problem. I do want to know – surajs1n Nov 15 '15 at 07:22
  • 1
    @psyco Limitations is misleading. A binary representation means that many values with exact decimal representation cannot be represented accurately. However, this is by design and binary floating point has many advantages. For its intended usage I don't believe a better design is possible. – David Heffernan Nov 15 '15 at 07:29
  • 1
    @psyco the other David and Jens and already explained it far more eloquently that I could have. The only thing I would add is that the issue you face is due to limited number of bits available to describe all possible floating point values. IEEE-754 double-precision format makes use of 1-sign bit, 11-bits for the exponent, leaving only 52 bits out of 64 for the remainder called the mantissa or significand. There simply are not enough bits to uniquely describe all possible floating point values exactly. – David C. Rankin Nov 15 '15 at 07:45
  • @DavidC.Rankin Thanks. Got it :) – surajs1n Nov 15 '15 at 07:47
  • 1
    Possible duplicate of [Is floating point math broken?](http://stackoverflow.com/questions/588004/is-floating-point-math-broken) – Thomas Padron-McCarthy Nov 15 '15 at 09:32

2 Answers2

1

The "standard" solution for that isn't pretty: use hexadecimal notation for all your floating point constants instead of decimal. They look like 0x1.7aP-13 something that is hard to digest for humans, unfortunately. But with them you have the guarantee that writing out and reading back in gives you exactly the same value.

The tools from the standard C library strtod, printf (with format %a) and similar support this if you have a C library that implements at least C99. One minor point that you must be careful about when using that is that the decimal point of printf is locale dependent. So if your locale has for example a , for that you must be sure to write and read with the same locale.

Jens Gustedt
  • 76,821
  • 6
  • 102
  • 177
1

In general what you are attempting to do is impossible. Floating point values use a binary representation and many values with terminating decimal representation do not have exact binary representations.

Fundamentally, if you wish to preserve the decimal representation then you should use a data type that represents that value as a decimal.

It might be worth pointing out the method that Python adopted for displaying floating point values. Python displays the shortest decimal representation whose nearest floating point value is the value being displayed.

Using 0.1 as an example, that value cannot be represented exactly in binary floating point. So the closest floating point value is used. When you ask for a decimal representation of that binary value, the Python runtime determines that 0.1 is the shortest representation such that float('0.1') == value.

If that approach would be of use to you then you should study this: https://bugs.python.org/issue1580

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490