Float point comparison-Newbie

P

prashna

Hi Guru's,

Is it OK to compare a float variable with 0 i.e if (float_var ==
0.0)?If it is not correct please let me know how to compare float
variable with 0.
Thanks in advance
 
G

Gordon Burditt

Is it OK to compare a float variable with 0 i.e if (float_var ==
0.0)?If it is not correct please let me know how to compare float
variable with 0.

It depends on how you calculated the float variable and why you are
comparing it to zero. Floating point calculations are often subject
to roundoff error. An expression like (10.0*0.1 - 1.0) is likely
to *NOT* come out exactly zero.

If the floating point variable got the value 0.0 because you assigned
the constant 0.0 to it, or you fed the text "0.0" into strtod() or
[sf]scanf() as a marker for the end of the data, you are likely
safe. The float variable will likely have exactly zero in it. On
the other hand, if you have calculated it by subtracting two numbers
that ought to be equal, you may not get exactly zero when you
mathematically would expect to.

There are two commonly used methods of comparing two floating point
variables for equality. One tests if they are equal within a certain
amount. The other tests if they are equal within a certain percentage.
The percentage method doesn't work too well if the value you are
comparing against is zero (division by zero or nearly zero tends
not to work well).

Generally, which method you use and how you figure the threshhold
should be determined by what the numbers represent, *NOT* the
characteristics of the floating point numbers. For example, in the
USA, you might omit sending out a bill if the amount due is within
half a cent of zero. (Presuming here you ARE supposed to send out
notices of credit balances). The "half a cent" number is determined
by the fact that there aren't any coins smaller than a cent, and
anything less than half a cent would be rounded to zero. It has
nothing to do with how many bits there are in a floating point
number.

(I prefer to use integer quantities of cents (or whatever currency)
and explicitly round to the nearest cent where necessary. Sometimes
the law (e.g. that governing sales tax) has peculiar laws about
rounding unlike any conventional methods of rounding.)

You might check whether two voltages are "equal enough" by testing
if they are within 2% of each other. The reason you might choose
2% is because that is the accuracy specification of the meter you
are using to measure voltages.

Gordon L. Burditt
 
T

Tim Prince

prashna said:
Hi Guru's,

Is it OK to compare a float variable with 0 i.e if (float_var ==
0.0)?If it is not correct please let me know how to compare float
variable with 0.
This may start a near flame war, surely there a plenty of posts on this
topic in the archives. If you mean data type float, may I suggest
consideration of
#include <float.h>
if(fabsf(float_var)<FLT_MIN)
or, if you mean double,
if(fabs(double_var)<DBL_MIN)
Not that I want to guess your context, of which you should take account.
 
M

Mike Wahler

prashna said:
Hi Guru's,

Is it OK to compare a float variable with 0 i.e if (float_var ==
0.0)?
Yes.

If it is not correct please let me know how to compare float
variable with 0.

if (float_var == 0)
/* do something */

or

if(float_var == 0.0)
/* do something */

But note that many real number operations which would
mathematically equal zero won't be exact, due to the
necessary finiteness of floating point representations.

-Mike
 
R

Richard Bos

Mike Wahler said:
if (float_var == 0)
/* do something */

or

if(float_var == 0.0)
/* do something */

But note that many real number operations which would
mathematically equal zero won't be exact, due to the
necessary finiteness of floating point representations.

Of course, if you do this comparison to avoid dividing by zero, rather
than to determine whether you have, say, no money left, then this is
exactly what you want (though beware of overflow).

Richard
 
H

Herbert Rosenau

Hi Guru's,

Is it OK to compare a float variable with 0 i.e if (float_var ==
0.0)?If it is not correct please let me know how to compare float
variable with 0.
Thanks in advance

There is the problem that an floating point is never prezise enough to
hold and coparsion to 0.0 exactly as expected. You should define a
delta that is near 0 and test that the variable is inside that delta,
meaning it is nearly, but not exactly 0 when it is inside and not 0
when it is outside the delta.

To calculate monetary values you should avoid using float/double
anyway as this types are too far from to be exact from that in any
case. Use long or long long with the decimal point in mind not in the
variable. That means store the value as cent instead of $.cent, as cm
instead of m.cm, calculate the the number of decimal digits you can
throw away and round the values to fit its ordinal at the right points
to get commercial correct results. Flotingpoint arithmetic will never
give you correct values for that but differences in ranges from 1 cent
to some $.
 
F

Flash Gordon

On 11 Nov 2004 03:07:27 GMT

There are two commonly used methods of comparing two floating point
variables for equality. One tests if they are equal within a certain
amount. The other tests if they are equal within a certain
percentage. The percentage method doesn't work too well if the value
you are comparing against is zero (division by zero or nearly zero
tends not to work well).

<snip>

I agree that those are probably the two most common methods.

A third method people should be aware of because it is subtly different
is comparing the numbers to x decimal places. So 0.14 and 0.16 are
*different* when compared to 1 decimal place but they are the same when
compared within +/- 0.1

This method is important amongst other things for checking if 2 numbers
will be output as the same value. This reminds me, I really should write
a routine to find the difference of the numbers when they are taken to x
decimal places which, for 0.16 - 0.14 to 1db would return 0.1
(I prefer to use integer quantities of cents (or whatever currency)
and explicitly round to the nearest cent where necessary. Sometimes
the law (e.g. that governing sales tax) has peculiar laws about
rounding unlike any conventional methods of rounding.)

<snip>

I completely agree with you.
 
L

Lawrence Kirby

There is the problem that an floating point is never prezise enough to
hold and coparsion to 0.0 exactly as expected.

Unless you have a situation where a zero value really is represented as
zero. This is more likely to happen at data entry rather than the result
of a calculation.
You should define a
delta that is near 0 and test that the variable is inside that delta,
meaning it is nearly, but not exactly 0 when it is inside and not 0 when
it is outside the delta.

If that is appropriate to the problem in hand.
To calculate monetary values you should avoid using float/double anyway
as this types are too far from to be exact from that in any case. Use
long or long long with the decimal point in mind not in the variable.

It is quite possible to use float/double for monetary values. You can
end up with exact results if you do it right.

Another classic example is the use of FFTs (Fast Fourier Transforms) to
implement efficient multiplication of numbers with HUGE numbers of digits.
Your input data is integral (i.e. the digits of the numbers to be
multiplied) and the result is integral and exact, but the intermediate
values of the calculation are anything but integral, indeed mathematically
irrational.
That means store the value as cent instead of $.cent, as cm instead of
m.cm, calculate the the number of decimal digits you can throw away and

If you're using integers you shouldn't be throwing anything away, if you
are your values are inexact and there is no benefit over using floating
point.
round the values to fit its ordinal at the right points to get
commercial correct results.

You can use similar techniques with floating point. For example if you
know a result will be an exact number of cents then you must

1. Perform error analysis to prove that the floating point
calculation error is less than 0.5 cents.

2. Round to the nearest cent when displaying the result.
Flotingpoint arithmetic will never give you
correct values for that but differences in ranges from 1 cent to some $.

In most cases if you use doubles the cumulative error is likely to be a
miniscule fraction of a cent. But of course the appropriate error analysis
is essential.

I'm not saying that using floating point variables is necessarily the best
way to represent monetary values, I am saying that the notion that
floating point can't be used in this way and produce exact results is just
plain wrong.

Lawrence
 
G

Gordon Burditt

There are two commonly used methods of comparing two floating point
<snip>

I agree that those are probably the two most common methods.

A third method people should be aware of because it is subtly different
is comparing the numbers to x decimal places. So 0.14 and 0.16 are

I object here to the use of the word DECIMAL. (try BINARY). You're
introducing roundoff problems where there may have been none before,
due to the fact that the overwhelming majority of floating point
implementations use binary floating point, and numbers like 0.1 are
infinite repeating fractions when represented as binary.
*different* when compared to 1 decimal place but they are the same when
compared within +/- 0.1
This method is important amongst other things for checking if 2 numbers
will be output as the same value. This reminds me, I really should write
a routine to find the difference of the numbers when they are taken to x
decimal places which, for 0.16 - 0.14 to 1db would return 0.1

There is no exact representation of 0.1 in binary floating point.
When dealing with floating point on computers, it is best to try
to purge the concept of "decimal places" from your mind completely,
and especially to avoid using that term in interface specifications
of functions.

Gordon L. Burditt
 
L

Lawrence Kirby

I object here to the use of the word DECIMAL. (try BINARY).

I suspect that the fact that it it is DECIMAL is the key issue here.
You're
introducing roundoff problems where there may have been none before,
due to the fact that the overwhelming majority of floating point
implementations use binary floating point, and numbers like 0.1 are
infinite repeating fractions when represented as binary.

Which is the problem - how to handle in binary floating point quantities
which are fundamentally decimal in nature (e.g. values in most monetary
systems).
There is no exact representation of 0.1 in binary floating point.

Which makes the binary floating point representation an approximation, but
output routines that output decimal should still produce the correct exact
result of 0.1. When you know a value can be expressed exactly to a limited
number of decimal places and the error is suitably limited, this is
possible.
When dealing with floating point on computers, it is best
to try to
purge the concept of "decimal places" from your mind completely, and
especially to avoid using that term in interface specifications of
functions.

Except when it is fundamental to the quantities you are dealing with.

However this level of discussion may be a bit much for a thread with
"Newbie" in the subject. :)

Lawrence
 
F

Flash Gordon

I suspect that the fact that it it is DECIMAL is the key issue here.

It is indeed. Customers don't like it if a report says something like:
Value 1.4, expected value 1.4, these values are different.
Which is the problem - how to handle in binary floating point
quantities which are fundamentally decimal in nature (e.g. values in
most monetary systems).
Yup.


Which makes the binary floating point representation an approximation,
but output routines that output decimal should still produce the
correct exact result of 0.1. When you know a value can be expressed
exactly to a limited number of decimal places and the error is
suitably limited, this is possible.

Indeed. You can print a report which says something like
Value 1.4, expected value 1.5, difference is 0.1
without ever having to exactly represent any of the numbers.
Except when it is fundamental to the quantities you are dealing with.

However this level of discussion may be a bit much for a thread with
"Newbie" in the subject. :)

Yup.

Thank's for saving me some typing, Lawrence.

If I had the time I would rewrite the SW using other techniques, such as
using a hand roled decimal floating point library. However, by rounding
off as accurately as possible to the correct number of decimal places at
the correct times, and using the correct method to compare to x decimal
places, I am getting the required degree of accurace.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,576
Members
45,054
Latest member
LucyCarper

Latest Threads

Top