From 32009f20515209bf90922b5417f5da970ca04fea Mon Sep 17 00:00:00 2001 From: Peter Lemenkov Date: Mon, 16 Feb 2026 22:06:32 +0100 Subject: [PATCH] [PATCH] Fix float16 pack/unpack on big-endian systems PyFloat_Pack2() and PyFloat_Unpack2() (and their underscore-prefixed predecessors) take an 'le' parameter where 0 means big-endian and 1 means little-endian storage. The code was passing PY_BIG_ENDIAN which evaluates to 0 on little-endian and 1 on big-endian - exactly the opposite of what is needed, since the bitstream always operates in big-endian (MSB-first) byte order. On little-endian systems PY_BIG_ENDIAN=0 happened to produce the correct result (big-endian storage), masking the bug. On big-endian systems PY_BIG_ENDIAN=1 caused little-endian storage, resulting in byte-swapped float16 values. Replace PY_BIG_ENDIAN with the literal 0 (= big-endian) to get consistent behavior across all architectures. Signed-off-by: Peter Lemenkov Assisted-by: Claude (Anthropic) --- src/bitstruct/c.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/bitstruct/c.c b/src/bitstruct/c.c index 0ab2ed0..4ec7493 100644 --- a/src/bitstruct/c.c +++ b/src/bitstruct/c.c @@ -430,11 +430,11 @@ static void pack_float_16(struct bitstream_writer_t *self_p, #if PY_VERSION_HEX >= 0x030B00A7 PyFloat_Pack2(PyFloat_AsDouble(value_p), (char*)&buf[0], - PY_BIG_ENDIAN); + 0); #else _PyFloat_Pack2(PyFloat_AsDouble(value_p), &buf[0], - PY_BIG_ENDIAN); + 0); #endif bitstream_writer_write_bytes(self_p, &buf[0], sizeof(buf)); } @@ -447,9 +447,9 @@ static PyObject *unpack_float_16(struct bitstream_reader_t *self_p, bitstream_reader_read_bytes(self_p, &buf[0], sizeof(buf)); #if PY_VERSION_HEX >= 0x030B00A7 - value = PyFloat_Unpack2((const char*)&buf[0], PY_BIG_ENDIAN); + value = PyFloat_Unpack2((const char*)&buf[0], 0); #else - value = _PyFloat_Unpack2(&buf[0], PY_BIG_ENDIAN); + value = _PyFloat_Unpack2(&buf[0], 0); #endif return (PyFloat_FromDouble(value));