====================================== | |
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 nan**0 and 1**nan. | |
>>> 1 + NAN | |
nan | |
>>> 1 * NAN | |
nan | |
>>> 0 * NAN | |
nan | |
>>> 1 ** NAN | |
1.0 | |
>>> NAN ** 0 | |
1.0 | |
>>> 0 ** NAN | |
nan | |
>>> (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 | |
==================== | |