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
1 change: 0 additions & 1 deletion Lib/test/test_long.py
Original file line number Diff line number Diff line change
Expand Up @@ -403,7 +403,6 @@ def check_float_conversion(self, n):
"Got {}, expected {}.".format(n, actual, expected))
self.assertEqual(actual, expected, msg)

@unittest.expectedFailure # TODO: RUSTPYTHON
@support.requires_IEEE_754
def test_float_conversion(self):

Expand Down
20 changes: 11 additions & 9 deletions crates/common/src/int.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,10 @@ use num_traits::{One, ToPrimitive, Zero};
#[must_use]
pub fn true_div(numerator: &BigInt, denominator: &BigInt) -> f64 {
let rational = Rational::from_integers_ref(numerator.into(), denominator.into());
match rational.rounding_into(RoundingMode::Nearest) {
// returned value is $t::MAX but still less than the original
(val, core::cmp::Ordering::Less) if val == f64::MAX => f64::INFINITY,
// returned value is $t::MIN but still greater than the original
(val, core::cmp::Ordering::Greater) if val == f64::MIN => f64::NEG_INFINITY,
(val, _) => val,
}
// Nearest rounding can return the largest finite value for a quotient
// slightly beyond it; overflow starts at the halfway rounding boundary.
let (rounded, _) = rational.rounding_into(RoundingMode::Nearest);
rounded
}

#[must_use]
Expand Down Expand Up @@ -202,11 +199,16 @@ fn word_all_ascii_digits(word: u64) -> bool {
(below | above) & 0x8080_8080_8080_8080 == 0
}

// num-bigint now returns Some(inf) for to_f64() in some cases, so just keep that the same for now
/// Convert an integer to a finite float, or return None when it overflows.
#[inline(always)]
#[must_use]
pub fn bigint_to_finite_float(int: &BigInt) -> Option<f64> {
int.to_f64().filter(|f| f.is_finite())
// malachite-bigint's ToPrimitive returns None when the input exceeds
// the largest finite magnitude, even when nearest rounding is finite.
let value = int
.to_f64()
.unwrap_or_else(|| true_div(int, &BigInt::one()));
value.is_finite().then_some(value)
}

#[cfg(test)]
Expand Down
Loading