1

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?

0

6 Answers 6

4

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.

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

Comments

1

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

Comments

1

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

Comments

1
>>> 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

Comments

1

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.

6 Comments

Wolfram Alpha confirms using rational arithmetic that the answer is exactly 18.5: wolframalpha.com/input/?i=47.36%2F1.6%2A%2A2
Look at fractions instead. Decimal doesn't handle rational numbers.
You're right, for some reason >>> Decimal(1.6)**2 Decimal('2.560000000000000284217094304') even though 1.6 * 1.6 clearly equals 2.56 on the nose.
@AndrewGorcester: That's probably due to the imprecision of 1.6 as a double. Try Decimal(16) / Decimal(10) and see what you get.
Passing the numbers into Decimal as strings also avoids the float representation issues - Decimal('47.36')/Decimal('1.6') ** 2 gives Decimal('18.5').
|
-3

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.

2 Comments

Nothing against numpy and it's a brilliant piece of work, but that's a pretty huge dependency to pull in just to compare a couple of floats.
yeah, you are right. Unless your are doing mathematical intensive program, it would be a burden to import it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.