python unittest2 assertAlmostEqual with `places` works incorrectly

291 Views Asked by At

I am dealing with the following problem with unittest2:

assertAlmostEqual(69.88, 69.875, places=2)  # returns True

but

assertAlmostEqual(1.28, 1.275, places=2)  # returns False

I think problem is in the assertAlmostEqual method:

def assertAlmostEqual(self, first, second, places=None, ...):
    if first == second:
        # shortcut
        return
    ...
    if delta is not None:
    ...
    else:
        if places is None:
            places = 7

        if round(abs(second-first), places) == 0:
            return

    ...
    raise self.failureException(msg)

Should it instead be:

if abs(round(second, places) - round(first, places)) == 0
    return
2

There are 2 best solutions below

0
jonrsharpe On BEST ANSWER

Your proposed fix doesn't make any difference, as you can easily demonstrate:

>>> places = 2
>>> first, second = 69.88, 69.875
>>> round(abs(second-first), places)
0.0
>>> abs(round(second, places) - round(first, places))
0.0

This is a problem with floating point precision, see e.g. Is floating point math broken? 69.88 cannot be represented exactly:

>>> "{:.40f}".format(69.88)
'69.8799999999999954525264911353588104248047'
0
user4600699 On

The difference in the second example is

0.005

And even without mentioned biases of floating points result of round will be 0.01, so these numbers really different with 2-places precision

This method compares difference between numbers. It is kinda standard of comparing float numbers actually

So the problem is not with implementation, but with you expectations, that is different from common float comparison