| ====================================== |
| 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 |
| ==================== |
| |