473,386 Members | 1,799 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,386 software developers and data experts.

Huge Floating Point Error

While debugging the following code:

#include <iostream>
using namespace std;
int main()
{
float f = 583312.0F * 0.1F;
cout << f << endl;
return 0;
}

The value of "f" as reported by the debugger is "58331.199" instead of
"58331.2". Note that the console output will correctly display
"58331.2". However, this is not just a "debugger-display" problem, this
problem was found since the errant data is actually being output to
Matlab data files.

I've tested this sample code on VC++ 6, 2002, and 2005. Both 2002 and
2005 exhibit this problem. Version 6 at least shows the correct result
while debugging.

Can this be "fixed" with some compile/link option? (Needed most for
2002)

Is there a patch available? A reasonable work-around?

This is so surprising I must be overlooking something very basic.

Mike

Nov 2 '06 #1
5 1188
<lo*******@yahoo.comwrote in message
news:11*********************@i42g2000cwa.googlegro ups.com...
While debugging the following code:

#include <iostream>
using namespace std;
int main()
{
float f = 583312.0F * 0.1F;
cout << f << endl;
return 0;
}

The value of "f" as reported by the debugger is "58331.199" instead of
"58331.2". Note that the console output will correctly display
"58331.2". However, this is not just a "debugger-display" problem, this
problem was found since the errant data is actually being output to
Matlab data files.

I've tested this sample code on VC++ 6, 2002, and 2005. Both 2002 and
2005 exhibit this problem. Version 6 at least shows the correct result
while debugging.

Can this be "fixed" with some compile/link option? (Needed most for
2002)

Is there a patch available? A reasonable work-around?

This is so surprising I must be overlooking something very basic.
What you are overlooking is that floating point arithmetic is inexact.

Declare your variable as a double rather than a float and you get greater
precision.

Regards,
Will
Nov 2 '06 #2
While debugging the following code:
>
#include <iostream>
using namespace std;
int main()
{
float f = 583312.0F * 0.1F;
cout << f << endl;
return 0;
}

The value of "f" as reported by the debugger is "58331.199" instead of
"58331.2". Note that the console output will correctly display
"58331.2". However, this is not just a "debugger-display" problem, this
problem was found since the errant data is actually being output to
Matlab data files.

I've tested this sample code on VC++ 6, 2002, and 2005. Both 2002 and
2005 exhibit this problem. Version 6 at least shows the correct result
while debugging.
There is no correct result. your value probably is 58331.1999999 and cout
probably truncates it after the nth digit.
floating point math is different from integer math.

google for 'what every programmer should know about floating point' and the
first n hits will explain exactly why you are having this problem, why it is
not bug, and why there is nothing you can do about it.
--

Kind regards,
Bruno van Dooren
br**********************@hotmail.com
Remove only "_nos_pam"
Nov 2 '06 #3
My mistake - hopefully this will make it more clear:

#include <iostream>
using namespace std;
int main(int argc, char **argv)
{
float f1 = (583312.0F * 0.1F);
cout << f1 << endl;
float f2 = (583313.0F * 0.1F);
cout << f2 << endl;
float f3 = f2 - f1;
cout << f3 << endl;
return 0;
}

f3 is 0.101563 instead of "0.1". I can accept the normally miniscule
epsilon. However, this is unacceptable - thus the statement of "Huge"
in regards to the error.
Mike


Bruno van Dooren [MVP VC++] wrote:
While debugging the following code:

#include <iostream>
using namespace std;
int main()
{
float f = 583312.0F * 0.1F;
cout << f << endl;
return 0;
}

The value of "f" as reported by the debugger is "58331.199" instead of
"58331.2". Note that the console output will correctly display
"58331.2". However, this is not just a "debugger-display" problem, this
problem was found since the errant data is actually being output to
Matlab data files.

I've tested this sample code on VC++ 6, 2002, and 2005. Both 2002 and
2005 exhibit this problem. Version 6 at least shows the correct result
while debugging.

There is no correct result. your value probably is 58331.1999999 and cout
probably truncates it after the nth digit.
floating point math is different from integer math.

google for 'what every programmer should know about floating point' and the
first n hits will explain exactly why you are having this problem, why it is
not bug, and why there is nothing you can do about it.
--

Kind regards,
Bruno van Dooren
br**********************@hotmail.com
Remove only "_nos_pam"
Nov 2 '06 #4
My mistake - hopefully this will make it more clear:
>
#include <iostream>
using namespace std;
int main(int argc, char **argv)
{
float f1 = (583312.0F * 0.1F);
cout << f1 << endl;
float f2 = (583313.0F * 0.1F);
cout << f2 << endl;
float f3 = f2 - f1;
cout << f3 << endl;
return 0;
}

f3 is 0.101563 instead of "0.1". I can accept the normally miniscule
epsilon. However, this is unacceptable - thus the statement of "Huge"
in regards to the error.
Floats (4 byte) have only 7 digits of precision
subtracting 58331.2 from 58331.3 and ending up with 0.101563 is correct,
because the last part '1563' starts from the 8th digit of precision.

floats are simply too small for what you want to do. You should either use
doubles, or multiply your result by 10, truncate it to only its integer part
and then divide by 10 again.

Another symptom of this behaviour: if you have to add a collection of
floats, the order in which you add them determines the outcome.
starting with the smallest values first will yield the most precise answer.
doing it any other way will give larger errors.

These things are implied by the floating point standard itself. The fact
that VC6 yield other results is because it does floating point stuff
differently from later compilers. But both are correct as far as floating
point behavior is concerned.

--

Kind regards,
Bruno van Dooren
br**********************@hotmail.com
Remove only "_nos_pam"
Nov 2 '06 #5
I understand now. Thank you for your help.

Mike
Bruno van Dooren [MVP VC++] wrote:
My mistake - hopefully this will make it more clear:

#include <iostream>
using namespace std;
int main(int argc, char **argv)
{
float f1 = (583312.0F * 0.1F);
cout << f1 << endl;
float f2 = (583313.0F * 0.1F);
cout << f2 << endl;
float f3 = f2 - f1;
cout << f3 << endl;
return 0;
}

f3 is 0.101563 instead of "0.1". I can accept the normally miniscule
epsilon. However, this is unacceptable - thus the statement of "Huge"
in regards to the error.

Floats (4 byte) have only 7 digits of precision
subtracting 58331.2 from 58331.3 and ending up with 0.101563 is correct,
because the last part '1563' starts from the 8th digit of precision.

floats are simply too small for what you want to do. You should either use
doubles, or multiply your result by 10, truncate it to only its integer part
and then divide by 10 again.

Another symptom of this behaviour: if you have to add a collection of
floats, the order in which you add them determines the outcome.
starting with the smallest values first will yield the most precise answer.
doing it any other way will give larger errors.

These things are implied by the floating point standard itself. The fact
that VC6 yield other results is because it does floating point stuff
differently from later compilers. But both are correct as far as floating
point behavior is concerned.

--

Kind regards,
Bruno van Dooren
br**********************@hotmail.com
Remove only "_nos_pam"
Nov 2 '06 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
by: Dave | last post by:
Hi folks, I am trying to develop a routine that will handle sphere-sphere and sphere-triangle collisions and interactions. My aim is to develop a quake style collision engine where a player can...
5
by: Steffen | last post by:
Hi, is it possible to have two fractions, which (mathematically) have the order a/b < c/d (a,b,c,d integers), but when (correctly) converted into floating point representation just have the...
4
by: Rajesh | last post by:
struct symbol { char ch; float probability; char *codeword; }; void get_user_input(struct symbol **sptr) { .....
4
by: jacob navia | last post by:
Hi people I continue to work in the tutorial for lcc-win32, and started to try to explain the floating point flags. Here is the relevant part of the tutorial. Since it is a difficult part, I...
4
by: alex | last post by:
hi friends ... i am facing a problem while detecting floating point operations in my project, please help me. i want to find out the places in my C/C++ project where i am doing floating...
1
by: Shhnwz.a | last post by:
Hi, I have a problem regarding handling floating point error, specially Denormalisation error. I want to know is there any trick or technique to find bit length of the resultant before using and...
15
by: Mukesh_Singh_Nick | last post by:
Why does floating point have a rounding error? How to work around it? For example, the following: flaot f = 1234.12345678F; printf("%2f\n", f) //prints 1234.123413 and
5
by: Keflavich | last post by:
Hey, I have a bit of code that died on a domain error when doing an arcsin, and apparently it's because floating point subtraction is having problems. I know about the impossibility of storing...
7
by: ma740988 | last post by:
Consider the equation (flight dynamics stuff): Yaw (Degrees) = Azimuth Angle(Radians) * 180 (Degrees) / 3.1415926535897932384626433832795 (Radians) There's a valid reason to use single...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.