In Python 3, I am checking whether a given value is triangular, that is, it can be represented as n * (n + 1) / 2
for some positive integer n
.
Can I just write:
import math def is_triangular1(x): num = (1 / 2) * (math.sqrt(8 * x + 1) - 1) return int(num) == num
Or do I need to do check within a tolerance instead?
epsilon = 0.000000000001 def is_triangular2(x): num = (1 / 2) * (math.sqrt(8 * x + 1) - 1) return abs(int(num) - num) < epsilon
I checked that both of the functions return same results for x
up to 1,000,000. But I am not sure if generally speaking int(x) == x
will always correctly determine whether a number is integer, because of the cases when for example 5 is represented as 4.99999999999997 etc.
As far as I know, the second way is the correct one if I do it in C, but I am not sure about Python 3.
Use the isinstance() function to check if a number is an int or float, e.g. if isinstance(my_num, int): . The isinstance function will return True if the passed in object is an instance of the provided class ( int or float ).
Casting the int to a float explicitly will do absolutely nothing. The int will be promoted to a float for purposes of comparison anyway.
Using int() function The function int(x) converts the argument x to an integer. If x is already an integer or a float with integral value, then the expression int(x) == x will hold true. That's all about determining whether a variable is an integer or not in Python.
There is is_integer
function in python float type:
>>> float(1.0).is_integer() True >>> float(1.001).is_integer() False >>>
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With