Solved

# TIniFile->ReadFloat   ---> precision changes

Posted on 2003-12-02
640 Views
Hi,

when i have in inifile:
valueX = 1,12

and i do
float x = ini->ReadFloat("some","valueX",0);

then x is not 1,12 but 1,12005678123 or something.  The precision has changed.  Anyone knows how i can easily solve this??

Thanks!

0
Question by:cleaverX
• 3
• 3
• 2

LVL 13

Expert Comment

ID: 9858497
What is your exact problem. On type of precision is the one for displaying a number. This effects only the output.
1.12000000000
1.12005678123
both have the same precision (11 digits after the decimal point).

Or are you concerned about the difference between those numbers? This is more likely to be a problem of change of base. For humans the decimal system is the one we are used to. Each digits can be 0-9. In the PC floating point numbers are represented similar to a scientific notation (1.12e0) but in a binary system. 1.12 seems to have no exact conversion to a floating point in the 2 base system. The nearest value is 1.12005678123.  To test for equality using floats it is safer to use
if (fabs (x - 1.12) < 0.00001)
if (x == 1.12)

0

Author Comment

ID: 9858633
SteH,

i need to work with correct floats.  When the inifile says  ValueX = 1,12 then i need a float that = 1,12.

It must NOT be 1,120123456 or something.  I can live with 1.12000000, 'cause that still is 1,12.  I only want to have the correct value to be in the float.
0

Author Comment

ID: 9858801
<<<<<Or are you concerned about the difference between those numbers?>>>>
YES, that's it
0

LVL 13

Expert Comment

ID: 9858867
I am not sure what internal format TIniFile uses but it seems to be float. There 1.12 is at most 1.12000. Going to double 1.1200000000000 can be achieved. Perhaps you can try it with ->ReadString and convert the string into a double and remove the last digits.
0

LVL 17

Expert Comment

ID: 9863078
If you compare a single precision float with a double precision constant, you will often find a difference. If you need to work in single precision make sure that your constants are also in single precision to avoid unexpected *apparent* loss of precision due to single->double promotion. I say *apparent* because what's really happening, is that you are attempting to deal with greater precision than you actually have, when single precision values are promoted to double precision.
--------8<--------
#include <iostream>
#include <cmath>

int main()
{
float f = 0.7; // Effectively this assignment is f = 0.7f, because f is single precision
std::cout << "Difference between f and its double precision assignment is " << fabs(f-0.7) << '\n';
std::cout << "Difference between f and its single precision assignment is " << fabs(f-0.7f) << '\n';
}
--------8<--------

If you get values like 1.12005678123, where you'd expect to have 1.12000000000, you are looking at the result of a calculation in which the error has become at least +/- 0.00006. You should be aware of (i.e. calculate) your error bounds and ensure that you display values to their appropriate precision.
--------8<--------
#include <iostream>
#include <cmath>
#include <iomanip>

int main()
{
float f = 1.12005678123; // Result of a calculation (say) with 0.1% error
std::cout << "f is " << std::fixed << std::setprecision(3) << f << " (to 3 decimal places)\n";
}
--------8<--------
0

Author Comment

ID: 9865061
rstaveley,

std::cout << "f is " << std::fixed << std::setprecision(3) << f << " (to 3 decimal places)\n";

the correct precision is set and displayed.  Can you set the correct precision directly to the float, before you display it.  What i mean is, can you do something like this:

float f1 = 0.1;    //precision = 10%
float f2 = 0.12;  //precision = 1%
float f3 = f1 * f2;   //maximum precision is 10 %; can you set the precision of 10% directly to f3, or can it only be set when you display it?

Thanks
0

LVL 13

Assisted Solution

SteH earned 20 total points
ID: 9865176
The precision rstaveley is only affecting the output in the string. It does not change the binary representation of the variable. What you might want is to do:

float f1 = 0.1f;
float f2 = 0.12f;
float f3 = 0.1 * floor (10. * (f1 * f2)); // all digits except the first after the decimal point are removed from the variable.

But do you really need this? Use a formatted output to get the desired precision when printing the var.
0

LVL 17

Accepted Solution

rstaveley earned 20 total points
ID: 9865586
> Can you set the correct precision directly to the float, before you display it.

No a float is primitive. It only stores a value. You need to store the error separately. The error is meta data.

If you asked me how tall I was and I said 187.9 cm and you wanted to put it into your program, you'd probably choose to put it into a floating point variable. The floating point variable has the ability to store the variable with a precision which is greater than the precision of the response I gave, so for completeness you should store the measurement and the error - i.e. 187.9 +/- 0.05 - because I didn't say 187.9000 +/- 0.00005 and by simply storing the value you lose the information indicating how precise the value is.

You could really do with a class which stores the value with its error and define a << operator to get the value to desplay to an appropriate number of significant decial places. The onus would still be with you to calculate errors.

e.g.

class DoubleWithError {
double value,error;
//....
};

I don't know of the existence of such a class, but I'm sure somebody has already come up with something like this with arithmetic operators which calculate errors appropriately. It is usually at this point that EE expert burcarpat points out something already in existence in the boost libraries!

e.g. This would be nice:

DoubleWithError x(187.9,0.05);
DoubleWithError y(10.0,0.05);
DoubleWithError z = x * y;
std::cout << "The answer is: " << z << '\n';

which could display
The answer is: 1879.0 +/- 9.9  (using display precision set by yourself)
or
The answer is: 1.8790e3 +/- 9.9e0 (using display precision set by yourself)
or
The answer is: 1.88e3  (using display precision calculated automatically to be appropriate for the error)
0

## Featured Post

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

### Suggested Solutions

Introduction This article is a continuation of the C/C++ Visual Studio Express debugger series. Part 1 provided a quick start guide in using the debugger. Part 2 focused on additional topics in breakpoints. As your assignments become a little more …
Basic understanding on "OO- Object Orientation" is needed for designing a logical solution to solve a problem. Basic OOAD is a prerequisite for a coder to ensure that they follow the basic design of OO. This would help developers to understand the b…
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…

#### 777 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.