Solved

TIniFile->ReadFloat   ---> precision changes

Posted on 2003-12-02
8
644 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

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

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

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 …
Many modern programming languages support the concept of a property -- a class member that combines characteristics of both a data member and a method.  These are sometimes called "smart fields" because you can add logic that is applied automaticall…
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.
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.

730 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