======================================

Python IEEE 754 floating point support

======================================



>>> from sys import float_info as FI

>>> from math import *

>>> PI = pi

>>> E = e



You must never compare two floats with == because you are not going to get

what you expect. We treat two floats as equal if the difference between them

is small than epsilon.

>>> EPS = 1E-15

>>> def equal(x, y):

...     """Almost equal helper for floats"""

...     return abs(x - y) < EPS





NaNs and INFs

=============



In Python 2.6 and newer NaNs (not a number) and infinity can be constructed

from the strings 'inf' and 'nan'.



>>> INF = float('inf')

>>> NINF = float('-inf')

>>> NAN = float('nan')



>>> INF

inf

>>> NINF

-inf

>>> NAN

nan



The math module's ``isnan`` and ``isinf`` functions can be used to detect INF

and NAN:

>>> isinf(INF), isinf(NINF), isnan(NAN)

(True, True, True)

>>> INF == -NINF

True



Infinity

--------



Ambiguous operations like ``0 * inf`` or ``inf - inf`` result in NaN.

>>> INF * 0

nan

>>> INF - INF

nan

>>> INF / INF

nan



However unambigous operations with inf return inf:

>>> INF * INF

inf

>>> 1.5 * INF

inf

>>> 0.5 * INF

inf

>>> INF / 1000

inf



Not a Number

------------



NaNs are never equal to another number, even itself

>>> NAN == NAN

False

>>> NAN < 0

False

>>> NAN >= 0

False



All operations involving a NaN return a NaN except for the power of *0* and *1*.

>>> 1 + NAN

nan

>>> 1 * NAN

nan

>>> 0 * NAN

nan

>>> 1 ** NAN

1.0

>>> 0 ** NAN

0.0

>>> (1.0 + FI.epsilon) * NAN

nan



Misc Functions

==============



The power of 1 raised to x is always 1.0, even for special values like 0,

infinity and NaN.



>>> pow(1, 0)

1.0

>>> pow(1, INF)

1.0

>>> pow(1, -INF)

1.0

>>> pow(1, NAN)

1.0



The power of 0 raised to x is defined as 0, if x is positive. Negative

values are a domain error or zero division error and NaN result in a

silent NaN.



>>> pow(0, 0)

1.0

>>> pow(0, INF)

0.0

>>> pow(0, -INF)

Traceback (most recent call last):

...

ValueError: math domain error

>>> 0 ** -1

Traceback (most recent call last):

...

ZeroDivisionError: 0.0 cannot be raised to a negative power

>>> pow(0, NAN)

nan





Trigonometric Functions

=======================



>>> sin(INF)

Traceback (most recent call last):

...

ValueError: math domain error

>>> sin(NINF)

Traceback (most recent call last):

...

ValueError: math domain error

>>> sin(NAN)

nan

>>> cos(INF)

Traceback (most recent call last):

...

ValueError: math domain error

>>> cos(NINF)

Traceback (most recent call last):

...

ValueError: math domain error

>>> cos(NAN)

nan

>>> tan(INF)

Traceback (most recent call last):

...

ValueError: math domain error

>>> tan(NINF)

Traceback (most recent call last):

...

ValueError: math domain error

>>> tan(NAN)

nan



Neither pi nor tan are exact, but you can assume that tan(pi/2) is a large value

and tan(pi) is a very small value:

>>> tan(PI/2) > 1E10

True

>>> -tan(-PI/2) > 1E10

True

>>> tan(PI) < 1E-15

True



>>> asin(NAN), acos(NAN), atan(NAN)

(nan, nan, nan)

>>> asin(INF), asin(NINF)

Traceback (most recent call last):

...

ValueError: math domain error

>>> acos(INF), acos(NINF)

Traceback (most recent call last):

...

ValueError: math domain error

>>> equal(atan(INF), PI/2), equal(atan(NINF), -PI/2)

(True, True)





Hyberbolic Functions

====================



