summaryrefslogtreecommitdiffstats
path: root/Doc
diff options
context:
space:
mode:
authorVictor Stinner <vstinner@python.org>2022-03-11 23:10:02 (GMT)
committerGitHub <noreply@github.com>2022-03-11 23:10:02 (GMT)
commit882d8096c262a5945e0cfdd706e5db3ad2b73543 (patch)
tree5e903c7e87a13203543e3e215f30b6b708df018d /Doc
parentecfff63e06e77e22035a7f7caa26986f033f3aea (diff)
downloadcpython-882d8096c262a5945e0cfdd706e5db3ad2b73543.zip
cpython-882d8096c262a5945e0cfdd706e5db3ad2b73543.tar.gz
cpython-882d8096c262a5945e0cfdd706e5db3ad2b73543.tar.bz2
bpo-46906: Add PyFloat_Pack8() to the C API (GH-31657)
Add new functions to pack and unpack C double (serialize and deserialize): * PyFloat_Pack2(), PyFloat_Pack4(), PyFloat_Pack8() * PyFloat_Unpack2(), PyFloat_Unpack4(), PyFloat_Unpack8() Document these functions and add unit tests. Rename private functions and move them from the internal C API to the public C API: * _PyFloat_Pack2() => PyFloat_Pack2() * _PyFloat_Pack4() => PyFloat_Pack4() * _PyFloat_Pack8() => PyFloat_Pack8() * _PyFloat_Unpack2() => PyFloat_Unpack2() * _PyFloat_Unpack4() => PyFloat_Unpack4() * _PyFloat_Unpack8() => PyFloat_Unpack8() Replace the "unsigned char*" type with "char*" which is more common and easy to use.
Diffstat (limited to 'Doc')
-rw-r--r--Doc/c-api/float.rst82
-rw-r--r--Doc/whatsnew/3.11.rst6
2 files changed, 88 insertions, 0 deletions
diff --git a/Doc/c-api/float.rst b/Doc/c-api/float.rst
index c107243..fd81683 100644
--- a/Doc/c-api/float.rst
+++ b/Doc/c-api/float.rst
@@ -76,3 +76,85 @@ Floating Point Objects
.. c:function:: double PyFloat_GetMin()
Return the minimum normalized positive float *DBL_MIN* as C :c:type:`double`.
+
+
+Pack and Unpack functions
+=========================
+
+The pack and unpack functions provide an efficient platform-independent way to
+store floating-point values as byte strings. The Pack routines produce a bytes
+string from a C :c:type:`double`, and the Unpack routines produce a C
+:c:type:`double` from such a bytes string. The suffix (2, 4 or 8) specifies the
+number of bytes in the bytes string.
+
+On platforms that appear to use IEEE 754 formats these functions work by
+copying bits. On other platforms, the 2-byte format is identical to the IEEE
+754 binary16 half-precision format, the 4-byte format (32-bit) is identical to
+the IEEE 754 binary32 single precision format, and the 8-byte format to the
+IEEE 754 binary64 double precision format, although the packing of INFs and
+NaNs (if such things exist on the platform) isn't handled correctly, and
+attempting to unpack a bytes string containing an IEEE INF or NaN will raise an
+exception.
+
+On non-IEEE platforms with more precision, or larger dynamic range, than IEEE
+754 supports, not all values can be packed; on non-IEEE platforms with less
+precision, or smaller dynamic range, not all values can be unpacked. What
+happens in such cases is partly accidental (alas).
+
+.. versionadded:: 3.11
+
+Pack functions
+--------------
+
+The pack routines write 2, 4 or 8 bytes, starting at *p*. *le* is an
+:c:type:`int` argument, non-zero if you want the bytes string in little-endian
+format (exponent last, at ``p+1``, ``p+3``, or ``p+6`` ``p+7``), zero if you
+want big-endian format (exponent first, at *p*).
+
+Return value: ``0`` if all is OK, ``-1`` if error (and an exception is set,
+most likely :exc:`OverflowError`).
+
+There are two problems on non-IEEE platforms:
+
+* What this does is undefined if *x* is a NaN or infinity.
+* ``-0.0`` and ``+0.0`` produce the same bytes string.
+
+.. c:function:: int PyFloat_Pack2(double x, unsigned char *p, int le)
+
+ Pack a C double as the IEEE 754 binary16 half-precision format.
+
+.. c:function:: int PyFloat_Pack4(double x, unsigned char *p, int le)
+
+ Pack a C double as the IEEE 754 binary32 single precision format.
+
+.. c:function:: int PyFloat_Pack8(double x, unsigned char *p, int le)
+
+ Pack a C double as the IEEE 754 binary64 double precision format.
+
+
+Unpack functions
+----------------
+
+The unpack routines read 2, 4 or 8 bytes, starting at *p*. *le* is an
+:c:type:`int` argument, non-zero if the bytes string is in little-endian format
+(exponent last, at ``p+1``, ``p+3`` or ``p+6`` and ``p+7``), zero if big-endian
+(exponent first, at *p*).
+
+Return value: The unpacked double. On error, this is ``-1.0`` and
+:c:func:`PyErr_Occurred` is true (and an exception is set, most likely
+:exc:`OverflowError`).
+
+Note that on a non-IEEE platform this will refuse to unpack a bytes string that
+represents a NaN or infinity.
+
+.. c:function:: double PyFloat_Unpack2(const unsigned char *p, int le)
+
+ Unpack the IEEE 754 binary16 half-precision format as a C double.
+
+.. c:function:: double PyFloat_Unpack4(const unsigned char *p, int le)
+
+ Unpack the IEEE 754 binary32 single precision format as a C double.
+
+.. c:function:: double PyFloat_Unpack8(const unsigned char *p, int le)
+
+ Unpack the IEEE 754 binary64 double precision format as a C double.
diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst
index ce15fb7..8ab6854 100644
--- a/Doc/whatsnew/3.11.rst
+++ b/Doc/whatsnew/3.11.rst
@@ -766,6 +766,12 @@ New Features
available directly (via :c:type:`PyCMethod`).
(Contributed by Petr Viktorin in :issue:`46613`.)
+* Add new functions to pack and unpack C double (serialize and deserialize):
+ :c:func:`PyFloat_Pack2`, :c:func:`PyFloat_Pack4`, :c:func:`PyFloat_Pack8`,
+ :c:func:`PyFloat_Unpack2`, :c:func:`PyFloat_Unpack4` and
+ :c:func:`PyFloat_Unpack8`.
+ (Contributed by Victor Stinner in :issue:`46906`.)
+
Porting to Python 3.11
----------------------