21

I'm developing a program that makes some floating points calculations. Is there any way to test my functions (which deliver floats) with doctests?

Fred Foo
  • 355,277
  • 75
  • 744
  • 836
malev
  • 235
  • 2
  • 5

5 Answers5

16

Sure, just format the floats with a reasonable format, based on your knowledge of what precision you expect them to exhibit -- e.g, if you expect accuracy to 2 digits after the decimal point, you could use:

''' Rest of your docstring and then...

    >>> '%.2f' % funcreturningfloat()
    '123.45'

'''
Alex Martelli
  • 854,459
  • 170
  • 1,222
  • 1,395
11

The following works for nosetests:

>>> 1/3.  # doctest: +ELLIPSIS
0.333...
Fred Foo
  • 355,277
  • 75
  • 744
  • 836
  • 1
    This works for repeating decimals (because their most significant digits aren't affected by floating point error), but not in general. For example, ">>> 1 - 10e-17" returns 0.9999999999..., which wouldn't be matched if you test for "1.0..." – SigmaX Apr 13 '19 at 00:21
10

The documentation has a suggestion

Floating-point numbers are also subject to small output variations across platforms, because Python defers to the platform C library for float formatting, and C libraries vary widely in quality here.

>>> 1./7  # risky
0.14285714285714285
>>> print 1./7 # safer
0.142857142857
>>> print round(1./7, 6) # much safer
0.142857
John La Rooy
  • 295,403
  • 53
  • 369
  • 502
4

You can use numtest - a doctest extension that simplifies the test of numerical results. https://pypi.python.org/pypi/numtest

>>> 1.0/3
0.333

Failed example: 1.0/3 Expected: 0.333 Got: 0.3333333333333333

>>> 1.0/3 # doctest: +NUMBER
0.333

import doctest
import numtest
doctest.testmod()

Process finished with exit code 0

All tests passed. No need for string formatting in your tests.

volodymyr
  • 7,256
  • 3
  • 42
  • 45
0

String format allows use test tuples.

>>> funcreturningfloattuple(1.0)
(1.0, 1.0)
>>> '%.2f, %.2f' % funcreturningfloattuple(1.0)
'1.00, 1.00'

>>> funcreturningfloattuple(1.4)
(1.3999999999999999, 1.3999999999999999)
>>> '%.2f, %.2f' % funcreturningfloattuple(1.4)
'1.40, 1.40'
sankari
  • 131
  • 6