Checking if float is equivalent to an integer value in python

You'll want to do the latter. In Programming in Python 3 the following example is given as the most accurate way to compare

def equal_float(a, b):
    #return abs(a - b) <= sys.float_info.epsilon
    return abs(a - b) <= chosen_value #see edit below for more info

Also, since epsilon is the "smallest difference the machine can distinguish between two floating-point numbers", you'll want to use <= in your function.

Edit: After reading the comments below I have looked back at the book and it specifically says "Here is a simple function for comparing floats for equality to the limit of the machines accuracy". I believe this was just an example for comparing floats to extreme precision but the fact that error is introduced with many float calculations this should rarely if ever be used. I characterized it as the "most accurate" way to compare in my answer, which in some sense is true, but rarely what is intended when comparing floats or integers to floats. Choosing a value (ex: 0.00000000001) based on the "problem domain" of the function instead of using sys.float_info.epsilon is the correct approach.

Thanks to S.Lott and Sven Marnach for their corrections, and I apologize if I led anyone down the wrong path.


Both your implementations have problems. It actually can happen that you end up with something like 4.999999999999997, so using int() is not an option.

I'd go for a completely different approach: First assume that your number is triangular, and compute what n would be in that case. In that first step, you can round generously, since it's only necessary to get the result right if the number actually is triangular. Next, compute n * (n + 1) / 2 for this n, and compare the result to x. Now, you are comparing two integers, so there are no inaccuracies left.

The computation of n can be simplified by expanding

(1/2) * (math.sqrt(8*x+1)-1) = math.sqrt(2 * x + 0.25) - 0.5

and utilizing that

round(y - 0.5) = int(y)

for positive y.

def is_triangular(x):
    n = int(math.sqrt(2 * x))
    return x == n * (n + 1) / 2

There is is_integer function in python float type:

>>> float(1.0).is_integer()
True
>>> float(1.001).is_integer()
False
>>>