Reputation: 22317
import numpy
import math
x = numpy.roots([2,-2,(21 - 21**2)])
print x[0], math.floor(x[0])
The output is:
15.0 14.0
and I expect
15.0 15.0
I don't expect any reason to have the floor equal to 14.0. Please explain!
Upvotes: 1
Views: 523
Reputation: 67073
I've used a function called fAlmostEqual
before, based on numpy's allclose function:
import math
def fAlmostEqual(a, b, rtol=1.0000000000000001e-05, atol=1e-08):
"""Checks if the given floats are almost equal. Uses the algorithm
from numpy.allclose."""
return math.fabs(a - b) <= (atol + rtol * math.fabs(b))
Creating a fuzzy floor function based on this:
def fuzzyFloor(v):
"""Returns the floor of the given number, unless it is equal to its
ceiling (within floating point error)."""
floor = math.floor(v)
if fAlmostEqual(floor+1, v):
return floor+1
return floor
print fuzzyFloor(14.9999999999999)
print fuzzyFloor(15)
print fuzzyFloor(14.99)
print fuzzyFloor(14.5)
This prints:
15.0
15.0
14.0
14.0
Upvotes: 2
Reputation: 45542
Your code does not give the same thing for me:
>>> import numpy
>>> import math
>>>
>>> x = numpy.roots([2,-2,(21 - 21**2)])
>>> print x[0], math.floor(x[0])
15.0 15.0
However, there is a number 14 lurking here. It's one of the roots:
>>> print x
[ 15. -14.]
Upvotes: 0
Reputation: 601739
Floating-point numbers are only approximations of some value, and all computations might introduce rounding errors. Printing a floating point-number might also round the number to fewer digits. Try
print repr(x[0]), repr(math.floor(x[0]))
to make sure all digits are shown. I guess it will show something like 14.9999999999999
.
Upvotes: 2
Reputation: 612993
It would seem that x[0]
is ever so slightly less than 15 and so floor
takes the value down to 14. The root finding algorithm is numerical rather than symbolic and floating point arithmetic is not exact.
Upvotes: 2