@@ -73,40 +73,34 @@ def round_float(
73
73
74
74
fsignificand = vpos * 2.0 ** - expval
75
75
76
- # Round
76
+ # Round.
77
77
isignificand = math .floor (fsignificand )
78
78
delta = fsignificand - isignificand
79
+
80
+ # Is the integer codepoint odd or even?
81
+ if rnd == RoundMode .TiesToEven :
82
+ code_is_odd = _isodd (isignificand )
83
+ if fi .precision == 1 : # When precision == 1, also check exponent.
84
+ code_is_odd = isignificand != 0 and _isodd (expval + bias )
85
+
86
+ # Rounded value will be either isignificand or isignificand+1.
79
87
if (
80
- (rnd == RoundMode .TowardPositive and not sign and delta > 0 )
81
- or (rnd == RoundMode .TowardNegative and sign and delta > 0 )
88
+ (
89
+ rnd == RoundMode .TiesToEven
90
+ and (delta > 0.5 or delta == 0.5 and code_is_odd )
91
+ )
82
92
or (rnd == RoundMode .TiesToAway and delta >= 0.5 )
83
- or (rnd == RoundMode .TiesToEven and delta > 0.5 )
84
- or (rnd == RoundMode .TiesToEven and delta == 0.5 and _isodd ( isignificand ) )
93
+ or (rnd == RoundMode .TowardPositive and not sign and delta > 0 )
94
+ or (rnd == RoundMode .TowardNegative and sign and delta > 0 )
85
95
):
86
96
isignificand += 1
97
+ if fi .precision == 1 and isignificand == 2 :
98
+ # Special case for p = 1: carry overflowed significand to exponent.
99
+ # (Not needed for p>1 as we are reconstructing, not encoding)
100
+ isignificand = 1
101
+ expval += 1
87
102
88
- ## Special case for Precision=1, all-log format with zero.
89
- if fi .precision == 1 :
90
- # The logic is simply duplicated for clarity of reading.
91
- isignificand = math .floor (fsignificand )
92
- code_is_odd = isignificand != 0 and _isodd (expval + bias )
93
- if (
94
- (rnd == RoundMode .TowardPositive and not sign and delta > 0 )
95
- or (rnd == RoundMode .TowardNegative and sign and delta > 0 )
96
- or (rnd == RoundMode .TiesToAway and delta >= 0.5 )
97
- or (rnd == RoundMode .TiesToEven and delta > 0.5 )
98
- or (rnd == RoundMode .TiesToEven and delta == 0.5 and code_is_odd )
99
- ):
100
- # Go to nextUp.
101
- # Increment isignificand if zero,
102
- # else increment exponent
103
- if isignificand == 0 :
104
- isignificand = 1
105
- else :
106
- assert isignificand == 1
107
- expval += 1
108
- ## End special case for Precision=1.
109
-
103
+ # Reconstruct from integer significand and exponent
110
104
result = isignificand * (2.0 ** expval )
111
105
112
106
if result == 0 :
0 commit comments