Skip to content

Commit badd6d8

Browse files
authored
Merge pull request #35 from graphcore-research/tidy-rounding
Tidy rounding
2 parents 0bb857a + b6a4179 commit badd6d8

File tree

3 files changed

+34
-31
lines changed

3 files changed

+34
-31
lines changed

docs/source/index.rst

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,13 @@ As well as block formats from |ocp_mx_link|.
5555
IEEE P3109
5656
</a>
5757

58+
Supported rounding modes include:
59+
60+
* Directed modes: Toward Zero, Toward Positive, Toward Negative
61+
* Round-to-nearest, with Ties to Even or Ties to Away
62+
* Stochastic rounding, with specified numbers of random bits
63+
64+
5865
Example
5966
-------
6067
This table (from example notebook :doc:`value-stats <02-value-stats>`) shows how
@@ -65,8 +72,8 @@ gfloat has been used to tabulate properties of various floating point formats.
6572
- P: Precision in bits
6673
- E: Exponent field width in bits
6774
- smallest: Smallest positive value
68-
- smallest_normal: Smallest positive normal value, NaN if no finite values are normal
69-
- max: Largest finite normal value, NaN if all finite values are subnormal
75+
- smallest_normal: Smallest positive normal value, n/a if no finite values are normal
76+
- max: Largest finite value
7077
- num_nans: Number of NaN values
7178
- num_infs: Number of infinities (2 or 0)
7279

docs/source/notebooks.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,4 @@ Some notebooks to illustrate uses of the library
1212
02-value-stats.ipynb
1313
03-value-tables.ipynb
1414
04-benchmark.ipynb
15+
05-stochastic-rounding.ipynb

src/gfloat/round.py

Lines changed: 24 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -88,40 +88,35 @@ def round_float(
8888
isignificand = math.floor(fsignificand)
8989
delta = fsignificand - isignificand
9090

91-
# fmt: off
92-
if (
93-
(rnd == RoundMode.TowardPositive and not sign and delta > 0)
94-
or (rnd == RoundMode.TowardNegative and sign and delta > 0)
95-
or (rnd == RoundMode.TiesToAway and delta >= 0.5)
96-
or (rnd == RoundMode.TiesToEven and delta > 0.5)
97-
or (rnd == RoundMode.TiesToEven and delta == 0.5 and _isodd(isignificand))
98-
or (rnd == RoundMode.Stochastic and delta > (0.5 + srbits) * 2.0**-srnumbits)
99-
):
100-
isignificand += 1
101-
102-
## Special case for Precision=1, all-log format with zero.
103-
# The logic is simply duplicated (and isignificand overwritten) for clarity.
104-
if fi.precision == 1:
105-
isignificand = math.floor(fsignificand)
106-
code_is_odd = isignificand != 0 and _isodd(expval + bias)
107-
if (
108-
(rnd == RoundMode.TowardPositive and not sign and delta > 0)
109-
or (rnd == RoundMode.TowardNegative and sign and delta > 0)
110-
or (rnd == RoundMode.TiesToAway and delta >= 0.5)
111-
or (rnd == RoundMode.TiesToEven and delta > 0.5)
112-
or (rnd == RoundMode.TiesToEven and delta == 0.5 and code_is_odd)
113-
or (rnd == RoundMode.Stochastic and delta > (0.5 + srbits) * 2.0**-srnumbits)
114-
):
115-
# Go to nextUp.
116-
# Increment isignificand if zero,
117-
# else increment exponent
91+
code_is_odd = (
92+
_isodd(isignificand)
93+
if fi.precision > 1
94+
else (isignificand != 0 and _isodd(expval + bias))
95+
)
96+
97+
if rnd == RoundMode.TowardZero:
98+
should_round_away = False
99+
if rnd == RoundMode.TowardPositive:
100+
should_round_away = not sign and delta > 0
101+
if rnd == RoundMode.TowardNegative:
102+
should_round_away = sign and delta > 0
103+
if rnd == RoundMode.TiesToAway:
104+
should_round_away = delta >= 0.5
105+
if rnd == RoundMode.TiesToEven:
106+
should_round_away = delta > 0.5 or (delta == 0.5 and code_is_odd)
107+
if rnd == RoundMode.Stochastic:
108+
should_round_away = delta > (0.5 + srbits) * 2.0**-srnumbits
109+
110+
if should_round_away:
111+
if fi.precision > 1:
112+
isignificand += 1
113+
else:
114+
# Increment isignificand if zero, else increment exponent
118115
if isignificand == 0:
119116
isignificand = 1
120117
else:
121118
assert isignificand == 1
122119
expval += 1
123-
## End special case for Precision=1.
124-
# fmt: on
125120

126121
# Reconstruct rounded result to float
127122
result = isignificand * (2.0**expval)

0 commit comments

Comments
 (0)