Skip to content

Commit b1c61c8

Browse files
committed
more readability
1 parent 4635f5e commit b1c61c8

File tree

2 files changed

+39
-37
lines changed

2 files changed

+39
-37
lines changed

src/gfloat/round.py

Lines changed: 31 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -72,40 +72,42 @@ def round_float(
7272
expval = max(expval, 1 - bias)
7373

7474
# Lift to "integer * 2^e"
75-
expval -= t
75+
expval = expval - p + 1
7676

7777
fsignificand = vpos * 2.0**-expval
7878

7979
# Round
8080
isignificand = math.floor(fsignificand)
81-
if isignificand != fsignificand:
82-
# Need to round
83-
if rnd == RoundMode.TowardZero:
84-
pass
85-
elif rnd == RoundMode.TowardPositive:
86-
isignificand += 1 if not sign else 0
87-
elif rnd == RoundMode.TowardNegative:
88-
isignificand += 1 if sign else 0
89-
else:
90-
# Round to nearest
91-
d = fsignificand - isignificand
92-
if d > 0.5:
93-
isignificand += 1
94-
elif d == 0.5:
95-
# Tie
96-
if rnd == RoundMode.TiesToAway:
97-
isignificand += 1
98-
else:
99-
# All other modes tie to even
100-
if fi.precision == 1:
101-
# No bits in significand
102-
assert (isignificand == 1) or (isignificand == 0)
103-
biased_exp = expval + bias
104-
if _isodd(biased_exp):
105-
expval += 1
106-
else:
107-
if _isodd(isignificand):
108-
isignificand += 1
81+
delta = fsignificand - isignificand
82+
if (
83+
(rnd == RoundMode.TowardPositive and not sign)
84+
or (rnd == RoundMode.TowardNegative and sign)
85+
or (rnd == RoundMode.TiesToAway and delta >= 0.5)
86+
or (rnd == RoundMode.TiesToEven and delta > 0.5)
87+
or (rnd == RoundMode.TiesToEven and delta == 0.5 and _isodd(isignificand))
88+
):
89+
isignificand += 1
90+
91+
## Special case for Precision=1, all-log format with zero.
92+
if fi.precision == 1:
93+
# The logic is simply duplicated for clarity of reading.
94+
isignificand = math.floor(fsignificand)
95+
code_is_odd = isignificand != 0 and _isodd(expval + bias)
96+
if (
97+
(rnd == RoundMode.TowardPositive and not sign)
98+
or (rnd == RoundMode.TowardNegative and sign)
99+
or (rnd == RoundMode.TiesToAway and delta >= 0.5)
100+
or (rnd == RoundMode.TiesToEven and delta > 0.5)
101+
or (rnd == RoundMode.TiesToEven and delta == 0.5 and code_is_odd)
102+
):
103+
# Go to nextUp.
104+
# Increment isignificand if zero,
105+
# else increment exponent
106+
if isignificand == 0:
107+
isignificand = 1
108+
else:
109+
assert isignificand == 1
110+
expval += 1
109111

110112
result = isignificand * (2.0**expval)
111113

test/test_round.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,6 @@
1010
from gfloat.formats import *
1111

1212

13-
def _mlround(v: float, dty: Type) -> float:
14-
"""
15-
Round `v` using ml_dtypes library
16-
"""
17-
return np.array([v]).astype(dty).astype(float).item()
18-
19-
2013
def test_round_p3109() -> None:
2114
fi = format_info_p3109(4)
2215
assert round_float(fi, 0.0068359375) == 0.0068359375
@@ -154,10 +147,17 @@ def _linterp(a: float, b: float, t: float) -> float:
154147
return a * (1 - t) + b * t
155148

156149

150+
def _mlround(v: float, dty: Type) -> float:
151+
"""
152+
Round `v` using ml_dtypes library
153+
"""
154+
return np.array([v]).astype(dty).astype(float).item()
155+
156+
157157
@pytest.mark.parametrize("fi,mldtype", test_formats)
158158
def test_ml_dtype_compatible(fi: FormatInfo, mldtype: Type) -> None:
159159
"""
160-
Test that rounding is compatible with ml_dtypes, assuming IEEE-like rounding
160+
Test that rounding is compatible with ml_dtypes
161161
"""
162162
for i in range(255):
163163
# For each float v, check values at various interpolations

0 commit comments

Comments
 (0)