Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/gfloat/round.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ def round_float(
case RoundMode.TowardNegative:
should_round_away = sign and delta > 0
case RoundMode.TiesToAway:
should_round_away = delta + 0.5 >= 1.0
should_round_away = delta >= 0.5
case RoundMode.TiesToEven:
should_round_away = delta > 0.5 or (delta == 0.5 and code_is_odd)
case RoundMode.ToOdd:
Expand Down
21 changes: 19 additions & 2 deletions test/test_round_underflow.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@

from typing import Callable

import math

import numpy as np
import pytest

from gfloat import FormatInfo, RoundMode, decode_float, encode_float
from gfloat import FormatInfo, RoundMode, Signedness, decode_float, encode_float
from gfloat import round_float, round_ndarray
from gfloat.formats import Domain, format_info_ocp_e8m0
from gfloat.formats import Domain, format_info_ocp_e8m0, format_info_p3109


def scalar_round(
Expand Down Expand Up @@ -41,6 +43,21 @@ def no_subnormal_format(precision: int, signed: bool = False) -> FormatInfo:
)


@pytest.mark.parametrize("rounder", [scalar_round, array_round])
@pytest.mark.parametrize("sign", [1, -1])
@pytest.mark.parametrize("direction", [0.0, 0.5, 1.0])
def test_round_ties_to_away_subnormal_midpoint(
rounder: Callable, sign: int, direction: float
) -> None:
fi = format_info_p3109(8, 3, Signedness.Signed, Domain.Extended)
midpoint = fi.smallest / 2
value = math.nextafter(midpoint, direction * fi.smallest)
expected = 0.0 if direction == 0.0 else sign * fi.smallest
actual = rounder(fi, sign * value, RoundMode.TiesToAway, False, 0)
assert actual == expected
assert np.signbit(actual) == np.signbit(expected)


@pytest.mark.parametrize("rounder", [scalar_round, array_round])
@pytest.mark.parametrize("rnd", RoundMode)
@pytest.mark.parametrize("sat", [False, True])
Expand Down
Loading