PEP 410: use :sup: and explain the loss of precision with other tuple formats

This commit is contained in:
Victor Stinner 2012-02-04 00:06:26 +01:00
parent d089c806d4
commit af7b317ea5
1 changed files with 30 additions and 18 deletions

View File

@ -30,12 +30,12 @@ Python 3.3 introduced functions supporting nanosecond resolutions:
* time module: clock_gettime(), clock_getres(), wallclock()
The Python float type uses binary64 format of the IEEE 754 standard. With a
resolution of 1 nanosecond (10^-9), float timestamps lose precision for values
bigger than 2^24 seconds (194 days: 1970-07-14 for an Epoch timestamp).
resolution of 1 nanosecond (10\ :sup:`-9`), float timestamps lose precision for values
bigger than 2\ :sup:`24` seconds (194 days: 1970-07-14 for an Epoch timestamp).
.. note::
With a resolution of 1 microsecond (10^-6), float timestamps lose precision
for values bigger than 2^33 seconds (272 years: 2242-03-16 for an Epoch
With a resolution of 1 microsecond (10\ :sup:`-6`), float timestamps lose precision
for values bigger than 2\ :sup:`33` seconds (272 years: 2242-03-16 for an Epoch
timestamp).
@ -107,17 +107,18 @@ Criteria:
Add a new IEEE 754-2008 quad-precision float type. The IEEE 754-2008 quad
precision float has 1 sign bit, 15 bits of exponent and 112 bits of mantissa.
128 bits float is supported by GCC (4.3), Clang and ICC. The problem is that
Visual C++ 2008 doesn't support it. Python must be portable and so cannot rely
on a type only available on some platforms. Another example: GCC 4.3 does not
support __float128 in 32-bit mode on x86 (but gcc 4.4 does).
128 bits float is supported by GCC (4.3), Clang and ICC compilers. Python must
be portable and so cannot rely on a type only available on some platforms. For
example, Visual C++ 2008 doesn't support it 128 bits float, whereas it is used
to build the official Windows executables. Another example: GCC 4.3 does not
support __float128 in 32-bit mode on x86 (but GCC 4.4 does).
Intel CPUs have FPU supporting 80-bit floats, but not using SSE intructions.
Other CPU vendors don't support this float size.
Intel CPUs have FPU (x87) supporting 80-bit floats, but not using SSE
intructions. Other CPU vendors don't support this float size.
There is also a license issue: GCC uses the MPFR library which is distributed
under the GNU LGPL license. This license is incompatible with the Python
license.
There is also a license issue: GCC uses the MPFR library for 128 bits float,
library distributed under the GNU LGPL license. This license is not compatible
with the Python license.
datetime.datetime
-----------------
@ -166,13 +167,24 @@ be zero.
Other formats have been proposed:
* A: (sec, nsec): value = sec + nsec * 10 ** -9
* B: (intpart, floatpart, exponent): value = intpart + floatpart * 10 ** exponent
* C: (intpart, floatpart, base, exponent): value = intpart + floatpart * base ** exponent
* A: (sec, nsec): value = sec + nsec * 10\ :sup:`-9`
* B: (intpart, floatpart, exponent): value = intpart + floatpart * 10\ :sup:`exponent`
* C: (intpart, floatpart, base, exponent): value = intpart + floatpart * base\ :sup:`exponent`
The format A only supports nanosecond resolution. Formats A and B lose
precision if the clock frequency is not a power of 10. The format C has a
similar issue.
precision if the clock frequency cannot be written as a power of 10: if the
clock frequency is not coprime with 2 and 5.
For some clocks, like ``QueryPerformanceCounter()`` on Windows, the frequency
is only known as runtime. The base and exponent has to be computed. If
computing the base and the exponent is too expensive (or not possible, e.g. if
the frequency is a prime number), exponent=1 can be used. The format (C) is
just a fractionn if exponent=1.
The only advantage of these formats is a small optimization if the base is 2
for float or if the base 10 for Decimal. In other cases, frequency = base\
:sup:`exponent` must be computed again to convert a timestamp as float or
Decimal. Storing directly the frequency in the denominator is simpler.
Alternatives: API design