diff --git a/src/simplefractions/__init__.py b/src/simplefractions/__init__.py index 15799f0..d1a84ea 100644 --- a/src/simplefractions/__init__.py +++ b/src/simplefractions/__init__.py @@ -37,7 +37,6 @@ import fractions import math import numbers -import struct import typing from simplefractions._simplest_in_interval import _simplest_in_interval @@ -115,6 +114,11 @@ def _interval_rounding_to( """ Return the interval of numbers that round to a given float. + Parameters + ---------- + x + A finite float. + Returns ------- left, right : fractions.Fraction @@ -123,22 +127,18 @@ def _interval_rounding_to( closed : bool True if the interval is closed at both ends, else False. """ - if x < 0: + if x < 0.0: left, right, closed = _interval_rounding_to(-x) return -right, -left, closed - if x == 0: - n = struct.unpack(" None: with self.subTest(f=f): self.check_simplest_from_float(f) + def test_simplest_from_float_open_closed_cases(self) -> None: + # Cases where it matters whether the interval rounding to + # the float is open or closed. + + # Even floats + self.assertEqual(simplest_from_float(1e16), 10**16 - 1) + self.assertEqual(simplest_from_float(1e16 + 4), 10**16 + 3) + self.assertEqual(simplest_from_float(float(2**54 - 4)), 2**54 - 5) + self.assertEqual(simplest_from_float(float(2**54)), 2**54 - 1) + self.assertEqual(simplest_from_float(float(2**54 + 8)), 2**54 + 6) + + # Odd floats + self.assertEqual(simplest_from_float(1e16 + 2), 10**16 + 2) + self.assertEqual(simplest_from_float(float(2**54 - 2)), 2**54 - 2) + self.assertEqual(simplest_from_float(float(2**54 + 4)), 2**54 + 3) + + def test_simplest_from_float_powers_of_two(self) -> None: + # Powers of two that are exactly representable in IEEE 754 binary64. + TWO = fractions.Fraction(2) + for e in range(-1074, 1024): + f = TWO**e + with self.subTest(f=f): + self.check_simplest_from_float(f) + def test_simplest_from_float_special_values(self) -> None: with self.assertRaises(ValueError): simplest_from_float(math.inf)