5

Possible Duplicate:
Why can't decimal numbers be represented exactly in binary?
Program not entering if statement

So I'm trying to run a program that has two variables, when one variable is equal to another, it performs a function. In this case, printing spam. However, for some reason, when I run this program, I'm not getting any output even though I know they are equal.

g=0.0 b=3.0 while g < 30.0: if g==b: print "Hi" g+=.1 print g, b 
2

3 Answers 3

9

You are assuming that adding .1 enough times to 0.0 will produce 3.0. These are floating point numbers, they are inaccurate. Rounding errors make it so that the value is never exactly equal to 3.0. You should almost never use == to test floating point numbers.

Sign up to request clarification or add additional context in comments.

4 Comments

If you really need Decimal math with accuracy, you can use the Decimal module. But why you would is beyond the data the op has provided
The actual value of g after adding 0.1 a thirty times is 3.0000000000000013.
Is this a viable alternative: g = round(g+0.1, 1) ?
+1 for saying “almost never” use == rather than “never.”
6

A good way to do this is to count with integer values (e.g., loop with i from 0 to 300 by 1) and scale the counter only when the float value is used (e.g., set f = i * .1). When you do this, the loop counter is always exact, so you get exactly the iterations you want, and there is only one floating-point rounding, which does not accumulate from iteration to iteration.

The loop counter is most commonly an integer type, so that addition is easily seen to be exact (until overflow is reached). However, the loop counter may also be a floating-point type, provided you are sure that the values and operations for it are exact. (The common 32-bit floating-point format represents integers exactly from -224 to +224. Outside that, it does not have the precision to represent integers exactly. It does not represent .1 exactly, so you cannot count with increments of .1. But you could count with increments of .5, .25, .375, or other small multiples of moderate powers of two, which are represented exactly.)

Comments

0

To expand on Karoly Horvath's comment, what you can do to test near-equality is choose some value (let's call it epsilon) that is very, very small relative to the minimum increment. Let's say epsilon is 1.0 * 10^-6, five orders of magnitude smaller than your increment. (It should probably be based on the average rounding error of your floating point representation, but that varies, and this is simply an example).

What you then do is check if g and b are less than epsilon different - if they are close enough that they are practically equal, the difference between practically and actually being the rounding error, which you're approximating with epsilon.

Check for

abs(g - b) < epsilon 

and you'll have your almost-but-not-quite equality check, which should be good enough for most purposes.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.