user1748573
user1748573

Reputation: 11

Simple Basic Python compare

I found this interesting question when I was doing homework we know, 47.36/1.6**2 == 18.5

but when I try to run the following code, it gives me a False(should be true)

print 47.36/1.6**2 == 18.5

Do anyone know what's going on?

Upvotes: 1

Views: 139

Answers (6)

Andrew Gorcester
Andrew Gorcester

Reputation: 19983

As others have said:

>>> 47.36/1.6**2
18.499999999999996

But, this is NOT due to a floating-point arithmetic problem as far as I can tell. Even if you use decimal math by wrapping the operands in Decimal() (after from decimal import Decimal) you will still get Decimal('18.49999999999999772404279952') as the answer.

It's possible I'm using Decimal() wrong here and my result also has some sort of floating point error; however, if I'm correct, that expression flat out does not equal 18.5, no matter what kind of math you use.

Edit: As Greg points out in the comments, the problem with my approach here is that Decimal(1.6) will just convert the float representation of 1.6, inaccuracies intact, into a Decimal. This gives the correct answer:

>>> Decimal('47.36') / Decimal('1.6')**2
Decimal('18.5')

Better still would be to use the fractions module as suggested by Kirk.

Upvotes: 1

Andrew Clark
Andrew Clark

Reputation: 208665

>>> 47.36/1.6**2
18.499999999999996

See this page on Floating Point Arithmetic: Issues and Limitations.

Here is how you can calculate this to exactly 18.5 without using any rounding or "close enough" behavior by using the decimal module:

>>> from decimal import Decimal
>>> Decimal('47.36') / Decimal('1.6')**2 == Decimal('18.5')
True
>>> float(Decimal('47.36') / Decimal('1.6')**2) == 18.5
True

Upvotes: 1

Harman
Harman

Reputation: 1581

47.36/1.6*2 return integer. So 47.36/1.6*2 would be 18, which is not equal to 18.5.

Edit

Sorry about that, actually it is being stored as 18.499999.
You should do this

import numpy as np
print np.around((47.36/1.6**2), decimals=1) == 18.5

This would return True.

Upvotes: -3

Kleg
Kleg

Reputation: 11

I would avoid checking for exact equality when comparing two floats. Instead take the difference and see if it is smaller than a value you consider close to zero.

(47.36/1.6**2 - 18.5) < 0.00000000001

will be

True

Upvotes: 1

Kirk Strauser
Kirk Strauser

Reputation: 30957

Short answer: IEEE 754 floating point can't exactly represent fractions where the denominator isn't a power of two, like 1/4, 1/16, 1/256, etc. You can get awfully close, given enough digits, but never quite exactly there.

You compare floating point numbers by defining "equals" as "within a certain delta". You could write something like:

def almost_equals(a, b, delta=0.0005):
    return abs(a - b) <= delta

and then test for "probably equal" with:

>>> almost_equals(47.36/1.6**2, 18.5)
True

Upvotes: 1

Greg Hewgill
Greg Hewgill

Reputation: 994639

You're probably getting an answer like 18.49999999999, which is not exactly equal to 18.5.

As always, the relevant reference for this is What Every Computer Scientist Should Know About Floating-Point Arithmetic.

Upvotes: 4

Related Questions