views:

141

answers:

6

Here's the code snippet:

float pNum = 9.2;
char* l_tmpCh = new char[255];

sprintf_s(l_tmpCh, 255, "%.9f", pNum);

cout << l_tmpCh << endl;

delete l_tmpCh;

the output is: 9.199999809
What to do in order for the result to be 9.200000000
Note: I need every float number printed with 9 decimals precision, so I don't want to have 9.2

A: 

Use a double literal rather than a float literal.

double pNum = 9.2;
char* l_tmpCh = new char[255];

sprintf_s(l_tmpCh, 255, "%.9f", pNum);

cout << l_tmpCh << endl;

delete l_tmpCh;

That f was making the literal a float; without it, the value is a double literal (more precise at about 15 decimal digits).

Of course, if 15 digits isn't enough, you're welcome to create your own class to represent values.

JoshD
A: 

This should do it:

double pNum = 9.2;

The f suffix makes it a float literal, which has only about 7 decimal digits of precision and of course suffers from representation errors. Assigning it to a double variable does not fix this. Of course, this assumes that float and double correspond to IEEE 754 single and double precision types.

EDIT: If you want to use float, then this problem cannot be solved at all. Read The Floating-Point Guide to understand why.

Michael Borgwardt
+8  A: 

The workaround is to not use floating point numbers..

Not every number can be represented accurately in the floating point format, such as, for example, 9.2. Or 0.1.

If you want all the decimals shown, then you get 9.199999809, because that's floating point value closest to 9.2.

If you use floating point numbers you have to accept this inaccuracy. Otherwise, your only option is to store the number in another format.

Required reading

jalf
+1 for linking "What Every Computer Scientist Should Know About Floating-Point Arithmetic".
DarkDust
A most boring and dry document.
Yehonatan
@Yehonatan: which is why I wrote http://floating-point-gui.de/
Michael Borgwardt
@Yehonatan: no one said using floating point correctly was easy. ;)
jalf
+1  A: 

What you're asking for is not possible in the general case since floating point numbers by definiton are approximations, which might or might not have an exact representation in decimal. Read the famous Goldberg paper: http://docs.sun.com/source/806-3568/ncg_goldberg.html

janneb
+3  A: 

There is no way a 32-bit binary float number have 9 digits of precision (there is only 7). You could fake it by appending 3 zeroes.

sprintf_s(l_tmpCh, 255, "%.6f000", pNum);

This won't work if the integer part exhausted a lot of precision already, e.g. 9222.2f will give 9222.200195000.

KennyTM
+1. Please consider referring to the `<cfloat>` and `<limits>` headers and the guarantees the C++ standard makes about float and double. IEEE-754 is not mandated. But there *are* other guarantees.
sellibitze
A: 

It's important to understand that native floating point numbers are seldom "accurate" because of the way they are represented in the computer. Thus most of the time you only get an approximation. And with printf, you also specify the precision with which to round that approximation to an output. E.g. "%.20f" will give you a representation that is rounded to 20 digits after the "."

DarkDust