184 lines
3.2 KiB
Plaintext
184 lines
3.2 KiB
Plaintext
======================================
|
|
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
|
|
====================
|
|
|