Im am doing a major project and after a long time debugging i found
this rather funny (=annoying) bug. In its simple form, this is the main
problem:
int main(void) {
float f1 = 0.3f;
float f2 = 0.1f;
printf("%f, %.10f, %f, %.10f\n", f1, f1, f2, f2);
if(f1 == 3*f2)
printf("%f == 3*%f\n", f1, f2);
if(f1 == 3.f*f2)
printf("%f == 3.0*%f\n", f1, f2);
return 0;
}
Output: 0.300000, 0.3000000119, 0.100000, 0.1000000015
Using MS Visual Studio 6 on a Windows XP box
So the problem is, that i need to do a more precise assignment of the
float variables, because the variable f1 is not 0.3 (and f2 is not 0.2)
but bigger. But how? 4 2222 jo*********@gmail.com wrote: Im am doing a major project and after a long time debugging i found this rather funny (=annoying) bug.
It's not a bug.
In its simple form, this is the main problem:
int main(void) { float f1 = 0.3f; float f2 = 0.1f; printf("%f, %.10f, %f, %.10f\n", f1, f1, f2, f2);
if(f1 == 3*f2) printf("%f == 3*%f\n", f1, f2);
if(f1 == 3.f*f2) printf("%f == 3.0*%f\n", f1, f2);
return 0; }
Output: 0.300000, 0.3000000119, 0.100000, 0.1000000015
Using MS Visual Studio 6 on a Windows XP box
So the problem is, that i need to do a more precise assignment of the float variables, because the variable f1 is not 0.3 (and f2 is not 0.2) but bigger. But how?
Use 'double'.
V
No sorry it's not a bug - but an error in my program. But the problem
is, that i need to check if the sum of two floats are greater than a
third float, and the floats do not have more than two dicimals! For
that purpose i do not need double - the float should be the right type! jo*********@gmail.com wrote: No sorry it's not a bug - but an error in my program. But the problem is, that i need to check if the sum of two floats are greater than a third float, and the floats do not have more than two dicimals! For that purpose i do not need double - the float should be the right type!
Look up "What Every Computer Scientist Should Know About Floating-Point
Arithmetic" on the Web. Read it. If some questions remain, ask them.
V
This happens because a floating point value tries to stuff (within a
set of boundaries, look for FLT_MAX, FLT_MIN) an unlimited number of
numbers in a 32 bit space. This means that not all numbers can be
represented exactly.
To counter this a value is used to denote a cut-off point after which
you declare that two floating point values differing less then that
cut-off value are equal. MSVC++ gives you a suggestion for this value
(FLT_EPSILON) for which if you add it to 1 you get a new value. So
1.0+FLT_EPSILON != 1.0
Note that this value is only really usuable for 1.0 and has to be
tweaked to fit the biggest floating point value you are using and the
amount of mathematical actions you perform on this value.
That is why I rather use another solution which might not be portable
to all OSes/compilers so test with care (the double version is
definately not portable due to no standards on a 64 bit integer).
IIRC MSVC++ 6 is IEEE 754 compliant.
That means you can do:
float FloatingPointValue1 = 0.3f,
FloatingPointValue2 = 0.1f*3.0f;
int ULPS = 2048;
if ((int)FloatingPointValue1 > ((int)FloatingPointValue2-ULPS) &&
(int)FloatingPointValue1 < ((int)FloatingPointValue2+ULPS))
{
printf("FloatingPointValue1 == FloatingPointValue2\n");
}
This works because the sign bit and the 8 exponent bits are
the most significant part of the value (according to IEEE 754).
So if you chose ULPS (for units in last place) ranging from 0 to 2^23-1
you are effectively saying how big of a difference between two floating
point values to ignore.
You still need to select the ULPS value with care (how much precision
do you want to retain, how much do you expect to lose in math, etc.)
but you lost the influence of the exponent on how big the epsilon
value should be.
The good thing about this trick is that you automatically check for
sign bit and due to the restrictions placed by 754 on how a floating
points are build up a difference in the exponent automatically means
that two values are not the same.
P.s. use include <iostream> instead of <stdio.h> and feed your output
to std::cout. This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics |
by: dan |
last post by:
Can someone tell me the difference between these three data types?
Thanks
Daniel
|
by: BigMan |
last post by:
How can I check if assignment of a float to a double (or vice versa)
will result in loss of precision?
|
by: BGP |
last post by:
I am working on a WIN32 API app using devc++4992 that will accept Dow
Jones/NASDAQ/etc. stock prices as input, parse them, and do things with
it. The user can just cut and paste back prices into a...
|
by: geskerrett |
last post by:
In the '80's, Microsoft had a proprietary binary structure to handle
floating point numbers, In a previous thread, Bengt Richter posted
some example code in how to convert these to python floats;...
|
by: Adam Warner |
last post by:
Hi all,
I'm used to ANSI Common Lisp implementations sanely printing single and
double floats. By sane I mean the printed decimal representation mimics
the underlying binary precision of the...
| |
by: my.correo.basura |
last post by:
Yesterday I found in a piece of code a float being incremented with ++.
For some reason (wrong, I guess...) I thought that only integer types
could be incremented that way, and I had never seen...
|
by: Michel Rouzic |
last post by:
I tried making a function that would fill half of an array with random
doubles that would go from -pi to +pi. Unfortunatly, all it ever
returns is -pi. I haven't used an already existing random...
|
by: godavemon |
last post by:
I need to take floats and dump out their 4 byte hex representation.
This is easy with ints with the built in hex function or even better
for my purpose
def hex( number, size ):
s =...
|
by: luca bertini |
last post by:
Hi,
i have strings which look like money values (ie 34.45)
is there a way to convert them into float variables?
everytime i try I get this error: "numb = float(my_line) ValueError:
empty string...
|
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,...
|
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: Hystou |
last post by:
Overview:
Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
|
by: tracyyun |
last post by:
Dear forum friends,
With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
|
by: agi2029 |
last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
|
by: conductexam |
last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
|
by: TSSRALBI |
last post by:
Hello
I'm a network technician in training and I need your help.
I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs.
The...
|
by: adsilva |
last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
| |
by: bsmnconsultancy |
last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence...
| |