Skip to content

Commit 34c9c6d

Browse files
committed
fix asymmetric check for rounding intervals + tests
1 parent 4c32b91 commit 34c9c6d

2 files changed

Lines changed: 34 additions & 1 deletion

File tree

src/csrc/dragon4.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1929,7 +1929,7 @@ Dragon4_PrintFloat_Sleef_quad(Sleef_quad *value, Dragon4_Options *opt)
19291929
/* mantissa_lo is unchanged */
19301930
exponent = floatExponent - 16383 - 112;
19311931
mantissaBit = 112;
1932-
hasUnequalMargins = (floatExponent != 1) && (mantissa_hi == 0 && mantissa_lo == 0);
1932+
hasUnequalMargins = (floatExponent != 1) && (mantissa_hi == (1ull << 48) && mantissa_lo == 0);
19331933
}
19341934
else {
19351935
/* subnormal */

tests/test_quaddtype.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,39 @@ def test_string_roundtrip():
308308
)
309309

310310

311+
def test_string_roundtrip_all_powers_of_two():
312+
"""Every exact power of two from the smallest subnormal up to overflow must
313+
round-trip through str() and repr(). Powers of two are the only values whose
314+
rounding interval is asymmetric, so they are the sole trigger for Dragon4
315+
margin bugs and are otherwise unreachable by random or decimal fuzzing."""
316+
two = QuadPrecision("2.0", backend="sleef")
317+
maxv = numpy_quaddtype.max_value
318+
p = numpy_quaddtype.smallest_subnormal
319+
320+
str_fails = []
321+
repr_fails = []
322+
tested = 0
323+
while True:
324+
tested += 1
325+
if QuadPrecision(str(p), backend="sleef") != p:
326+
str_fails.append(str(p))
327+
repr_inner = repr(p).split("'")[1]
328+
if QuadPrecision(repr_inner, backend="sleef") != p:
329+
repr_fails.append(repr(p))
330+
nxt = p * two
331+
if not (abs(nxt) <= maxv):
332+
break
333+
p = nxt
334+
335+
assert tested > 30000, f"expected the full power-of-two sweep, only tested {tested}"
336+
assert not str_fails, (
337+
f"{len(str_fails)} powers of two failed str() round-trip, e.g. {str_fails[:5]}"
338+
)
339+
assert not repr_fails, (
340+
f"{len(repr_fails)} powers of two failed repr() round-trip, e.g. {repr_fails[:5]}"
341+
)
342+
343+
311344
class TestBytesSupport:
312345
"""Test suite for QuadPrecision bytes input support."""
313346

0 commit comments

Comments
 (0)