floating point in 2.0

Randolph Brown rgb at panix.com
Sat Jun 9 19:45:17 EDT 2001


In article <9fm9kg05qs at enews1.newsguy.com>,
Alex Martelli <aleaxit at yahoo.com> wrote:
>I recall those darned globals that
>broke my routines when used in somebody else's workspaces as
>the worst blights on an otherwise interesting language

Certainly relatively obscure globals changing the behavior of ==, < and the
like are very dangerous, but comparing floats correctly is non-obvious, so
putting some operations in the default library and pointing to them in the
documentation for floats might be a good way of preventing beginners from 
shooting themselves in the foot:

# warning! not terribly tested code follows:

import math

def tolerates(x, y, tol):
  """
  are the floating point values x and y within a reasonable tolerance tol of
  each other?  The tolerance scales with the two numbers (a tolerance of 1E-9
  is pretty large around 1, but you need to scale that for numbers in the
  millions.)

  See Kuth TAoCP v.2 4.2.2
  """
  _, ex = math.frexp(x)
  _, ey = math.frexp(y)
  return math.fabs(x - y) < tol * math.ldexp(1, max(ex, ey))

# really, though, it may make more sense in some cases to specify your
# tolerance as an exponent in base 2, and then you can do some more stuff as
# integer arithmetic:
#
# Warning! no performance checks yet done!
def tolBase2(x, y, tol):
  "e.g. tolBase2(x, y, -5) == tolerance(x, y, 2**-5)"
  _, ex = math.frexp(x)
  _, ey = math.frexp(y)
  return math.fabs(x - y) < math.ldexp(1, max(ex+tol, ey+tol))

# maybe also a tolerance that uses ULPs too?


Then we get :
>>> e=1E-9              
>>> tolerates(1.0, 1.0, e)
1
>>> tolerates(1.0, 1.1, e)
0
>>> tolerates(1E-10, 1.1e-10, e)
0
>>> tolerates(1e-20, 1.1e-20, e)
0
>>> 1e-20 == 1e-10*1e-10
0
>>> 1e-20
9.9999999999999995e-21
>>> 1e-10*1e-10
1.0000000000000001e-20
>>> tolerates(1e-20, 1e-10*1e-10, e)
1
>>> tolerates(1e-20, 0, e)
1

# note that the reason that last part worked is the encoding of 0:
>>> import math
>>> math.frexp(0)
(0.0, 0)

	-Randy



More information about the Python-list mailing list