9

I have been looking around to find a general way of comparing two numerics in Python. In particular, I want to figure out whether they are the same or not.

The numeric types in Python are:

int, long, float & complex 

For example, I can compare 2 integers (a type of numeric) by simply saying:

a == b 

For floats, we have to be more careful due to rounding precision, but I can compare them within some tolerance.

Question

We get 2 general numerics a and b: How do we compare them? I was thinking of casting both to complex (which would then have a 0 imaginary part if the type is, say, int) and compare in that domain?

This question is more general than simply comparing floats directly. Certainly, it is related to this problem, but it is not the same.

0

3 Answers 3

7

In Python 3.5 (and in Numpy) you can use isclose

Read the PEP 485 that describes it, Python 3.5 math library listing and numpy.isclose for more. The numpy version works in all versions of Python that numpy is supported.

Examples:

>>> from math import isclose >>> isclose(1,1.00000000001) True >>> isclose(1,1.00001) False 

The relative and absolute tolerance can be changed.

Relative tolerance can be thought of as +- a percentage between the two values:

>>> isclose(100,98.9, rel_tol=0.02) True >>> isclose(100,97.1, rel_tol=0.02) False 

The absolute tolerance is a absolute value between the two values. It is the same as the test of abs(a-b)<=tolerance

All numeric types of Python are support with the Python 3.5 version. (Use the cmath version for complex)

I think longer term, this is your better bet for numerics. For older Python, just import the source. There is a version on Github.

Or, (forgoing error checking and inf and NaN support) you can just use:

def myisclose(a, b, *, rel_tol=1e-09, abs_tol=0.0): return abs(a-b) <= max( rel_tol * max(abs(a), abs(b)), abs_tol ) 
Sign up to request clarification or add additional context in comments.

1 Comment

+1 for that isclose GitHub library. As they say: They short circuit for exact equality, but then dive into a more careful check if not strict equality. That is what I was thinking (even handling complex types).
5

If you are looking to compare different types of numerics, there is nothing wrong with the == operator: Python will handle the type-casting. Consider the following:

>>> 1 == 1 + 0j == 1.0 True 

In cases where you are doing mathematical operations that could result in loss of precision (especially with floats), a common technique is to check if the values are within a certain tolerance. For example:

>>> (10**.5)**2 10.000000000000002 >>> (10**.5)**2 == 10 False 

In this case, you can find the absolute value of the difference and make sure it is under a certain threshold:

>>> abs((10**.5)**2 - 10) < 1e-10 True 

3 Comments

I guess my concern arises with tolerance, how does that work?
@denvar I added something for tolerance
@denvar check stackoverflow.com/questions/5595425/… for comparing with tolerance. I don't think that answer works with complex numbers though.
4

Why not just use == ?

>>1 == (1+0j) True >>1.0 == 1 True 

I'm pretty sure this works for all numeric types.

2 Comments

Haha, identical answers :)
It even works for bools - True==1.0 and False==0.0 both return True.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.