Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Testing floating point equality

Is there a function to test floating point approximate equality in python? Something like,

 def approx_equal(a, b, tol):      return abs(a - b) < tol 

My use case is similar to how Google's C++ testing library, gtest.h, defines EXPECT_NEAR.

Here is an example:

def bernoulli_fraction_to_angle(fraction):     return math.asin(sqrt(fraction)) def bernoulli_angle_to_fraction(angle):     return math.sin(angle) ** 2 def test_bernoulli_conversions():     assert(approx_equal(bernoulli_angle_to_fraction(pi / 4), 0.5, 1e-4))     assert(approx_equal(               bernoulli_fraction_to_angle(bernoulli_angle_to_fraction(0.1)),                 0.1, 1e-4)) 
like image 324
Neil G Avatar asked Oct 26 '10 23:10

Neil G


People also ask

Does == work for floats?

In the case of floating-point numbers, the relational operator (==) does not produce correct output, this is due to the internal precision errors in rounding up floating-point numbers.

How do you know if two floats are equal?

This is a fast initial check. if both numbers are any of +0, -0 or subnormal, numbers are equal. if exponents have difference exactly 1, shift correctly the fraction from one of the numbers. If difference of 2 fractions is small, numbers are equal.

Why floating point numbers should not be used for equality in expression?

This is because floating point values are not precise, and small rounding errors in the floating point operands may cause unexpected results.

Is it possible to compare floats for equality in Python?

How To Compare Floats in Python. If abs(a - b) is smaller than some percentage of the larger of a or b , then a is considered sufficiently close to b to be "equal" to b . This percentage is called the relative tolerance. You can specify the relative tolerance with the rel_tol keyword argument of math.


2 Answers

  • For comparing numbers, there is math.isclose.
  • For comparing numbers or arrays, there is numpy.allclose.
  • For testing numbers or arrays, there is numpy.testing.assert_allclose
like image 102
Neil G Avatar answered Sep 28 '22 00:09

Neil G


Another approach is to compute the relative change (or relative difference) of the two numbers, which is "used to compare two quantities while taking into account the 'sizes' of the things being compared". The two formulas mentioned in the Wikipedia article could be used in comparisons like the following in Python, which also handle cases where one or both of the values being compared are zero:

def approx_equal(a, b, tol):     return abs(a-b) <= max(abs(a), abs(b)) * tol  def approx_equal(a, b, tol):     return abs(a-b) <= (abs(a)+abs(b))/2 * tol 

The calculated value in either case is a unitless fraction. In the first case the baseline value is the maximum absolute value of the two numbers and in the second it's their mean absolute value. The article discusses each in more detail as well as their pros and cons. The latter can turned into a percentage difference if multiplied by 100 before the comparison (with tol becoming a percentage value). Note that the article suggests that if the changing value "is a percentage itself, it is better to talk about its change by using percentage points" — i.e. absolute change.

Both of these methods (obviously) require a little more computation than simply taking the absolute value of the difference of the two numbers, which might be a consideration.

like image 28
martineau Avatar answered Sep 28 '22 01:09

martineau