Solved

TIniFile->ReadFloat   ---> precision changes

Posted on 2003-12-02
8
632 Views
Last Modified: 2008-02-01
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
Comment
Question by:cleaverX
  • 3
  • 3
  • 2
8 Comments
 
LVL 13

Expert Comment

by:SteH
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)
instead of
if (x == 1.12)

Was this your question?
0
 

Author Comment

by:cleaverX
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

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

Expert Comment

by:SteH
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
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 17

Expert Comment

by:rstaveley
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

by:cleaverX
ID: 9865061
rstaveley,

in your example

  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

by:SteH
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

by:
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

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Suggested Solutions

Written by John Humphreys C++ Threading and the POSIX Library This article will cover the basic information that you need to know in order to make use of the POSIX threading library available for C and C++ on UNIX and most Linux systems.   [s…
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 …
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

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

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

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

15 Experts available now in Live!

Get 1:1 Help Now