diff --git a/pyiceberg/avro/decoder_fast.pyx b/pyiceberg/avro/decoder_fast.pyx index 52caec3308..ffd23dd977 100644 --- a/pyiceberg/avro/decoder_fast.pyx +++ b/pyiceberg/avro/decoder_fast.pyx @@ -138,7 +138,7 @@ cdef class CythonBinaryDecoder: """ return float(STRUCT_FLOAT.unpack(self.read(4))[0]) - cpdef float read_double(self): + cpdef double read_double(self): """Reads a value from the stream as a double. A double is written as 8 bytes. diff --git a/tests/avro/test_decoder.py b/tests/avro/test_decoder.py index 163ad8405e..1cf8346347 100644 --- a/tests/avro/test_decoder.py +++ b/tests/avro/test_decoder.py @@ -160,6 +160,23 @@ def test_read_double(decoder_class: Callable[[bytes], BinaryDecoder]) -> None: assert decoder.read_double() == 19.25 +@pytest.mark.parametrize("decoder_class", AVAILABLE_DECODERS) +@pytest.mark.parametrize( + "value", + [ + 3.141592653589793, + 429496729622.314, + 0.1, + 1.0000000000000002, # smallest double above 1.0 + 1e308, # overflows to inf in single precision + 5e-324, # underflows to 0.0 in single precision + ], +) +def test_read_double_keeps_full_precision(decoder_class: Callable[[bytes], BinaryDecoder], value: float) -> None: + decoder = decoder_class(struct.pack(" None: decoder = decoder_class(b"\x00\x00\x00\x00\x00\x40\x33\x40")