diff --git a/crates/libm-test/Cargo.toml b/crates/libm-test/Cargo.toml index 3a1ba8796..888cba5a0 100644 --- a/crates/libm-test/Cargo.toml +++ b/crates/libm-test/Cargo.toml @@ -39,7 +39,7 @@ paste = "1.0.15" rand = "0.8.5" rand_chacha = "0.3.1" rayon = "1.10.0" -rug = { version = "1.26.1", optional = true, default-features = false, features = ["float", "integer", "std"] } +rug = { git = "https://gitlab.com/tspiteri/rug.git", rev = "96d26fff459cc6be3f6c505a5bc55d14b9ac0222", optional = true, default-features = false, features = ["float", "integer", "std"] } [target.'cfg(target_family = "wasm")'.dependencies] # Enable randomness on WASM diff --git a/crates/libm-test/src/mpfloat.rs b/crates/libm-test/src/mpfloat.rs index a404f227b..a01a502bb 100644 --- a/crates/libm-test/src/mpfloat.rs +++ b/crates/libm-test/src/mpfloat.rs @@ -4,13 +4,10 @@ //! a struct named `Operation` that implements [`MpOp`]. use std::cmp::Ordering; -use std::ffi::{c_int, c_long}; use az::Az; -use gmp_mpfr_sys::mpfr::rnd_t; use rug::Assign; pub use rug::Float as MpFloat; -use rug::float::Round; use rug::float::Round::Nearest; use rug::ops::{PowAssignRound, RemAssignRound}; @@ -318,13 +315,8 @@ macro_rules! impl_op_for_ty { } fn run(this: &mut Self::MpTy, input: Self::RustArgs) -> Self::RustRet { - // Implementation taken from `rug::Float::to_f32_exp`. this.assign(input.0); - let exp = this.get_exp().unwrap_or(0); - if exp != 0 { - *this >>= exp; - } - + let exp = this.frexp_mut(); (prep_retval::(this, Ordering::Equal), exp) } } @@ -414,28 +406,20 @@ macro_rules! impl_op_for_ty { } impl MpOp for crate::op::[]::Routine { - type MpTy = (MpFloat, MpFloat, MpFloat); + type MpTy = (MpFloat, MpFloat); fn new_mp() -> Self::MpTy { ( new_mpfloat::(), new_mpfloat::(), - new_mpfloat::() ) } fn run(this: &mut Self::MpTy, input: Self::RustArgs) -> Self::RustRet { this.0.assign(input.0); this.1.assign(input.1); - let (ord, ql) = mpfr_remquo(&mut this.2, &this.0, &this.1, Nearest); - - // `remquo` integer results are sign-magnitude representation. Transfer the - // sign bit from the long result to the int result. - let clear = !(1 << (c_int::BITS - 1)); - let sign = ((ql >> (c_long::BITS - 1)) as i32) << (c_int::BITS - 1); - let q = (ql as i32) & clear | sign; - - (prep_retval::(&mut this.2, ord), q) + let (ord, q) = this.0.remainder_quo31_round(&this.1, Nearest); + (prep_retval::(&mut this.0, ord), q) } } @@ -545,24 +529,3 @@ impl MpOp for crate::op::nextafterf::Routine { unimplemented!("nextafter does not yet have a MPFR operation"); } } - -/// `rug` does not provide `remquo` so this exposes `mpfr_remquo`. See rug#76. -fn mpfr_remquo(r: &mut MpFloat, x: &MpFloat, y: &MpFloat, round: Round) -> (Ordering, c_long) { - let r = r.as_raw_mut(); - let x = x.as_raw(); - let y = y.as_raw(); - let mut q: c_long = 0; - - let round = match round { - Round::Nearest => rnd_t::RNDN, - Round::Zero => rnd_t::RNDZ, - Round::Up => rnd_t::RNDU, - Round::Down => rnd_t::RNDD, - Round::AwayZero => rnd_t::RNDA, - _ => unreachable!(), - }; - - // SAFETY: mutable and const pointers are valid and do not alias, by Rust's rules. - let ord = unsafe { gmp_mpfr_sys::mpfr::remquo(r, &mut q, x, y, round) }; - (ord.cmp(&0), q) -} diff --git a/crates/libm-test/src/precision.rs b/crates/libm-test/src/precision.rs index 800425f12..107d32a22 100644 --- a/crates/libm-test/src/precision.rs +++ b/crates/libm-test/src/precision.rs @@ -408,15 +408,6 @@ impl MaybeOverride<(f32, f32)> for SpecialCase { ) -> CheckAction { binop_common(input, actual, expected, ctx) } - - fn check_int( - _input: (f32, f32), - actual: I, - expected: I, - ctx: &CheckCtx, - ) -> CheckAction { - remquo_common(actual, expected, ctx) - } } impl MaybeOverride<(f64, f64)> for SpecialCase { @@ -428,15 +419,6 @@ impl MaybeOverride<(f64, f64)> for SpecialCase { ) -> CheckAction { binop_common(input, actual, expected, ctx) } - - fn check_int( - _input: (f64, f64), - actual: I, - expected: I, - ctx: &CheckCtx, - ) -> CheckAction { - remquo_common(actual, expected, ctx) - } } #[cfg(f128_enabled)] @@ -499,19 +481,6 @@ fn binop_common( DEFAULT } -fn remquo_common(actual: I, expected: I, ctx: &CheckCtx) -> CheckAction { - // FIXME: Our MPFR implementation disagrees with musl and may need to be updated. - if ctx.basis == CheckBasis::Mpfr - && ctx.base_name == BaseName::Remquo - && expected == I::MIN - && actual == I::ZERO - { - return XFAIL("remquo integer mismatch"); - } - - DEFAULT -} - impl MaybeOverride<(i32, f32)> for SpecialCase { fn check_float( input: (i32, f32), diff --git a/crates/util/Cargo.toml b/crates/util/Cargo.toml index acf5db704..378fde0c4 100644 --- a/crates/util/Cargo.toml +++ b/crates/util/Cargo.toml @@ -16,4 +16,4 @@ libm = { path = "../..", default-features = false } libm-macros = { path = "../libm-macros" } libm-test = { path = "../libm-test", default-features = false } musl-math-sys = { path = "../musl-math-sys", optional = true } -rug = { version = "1.26.1", optional = true, default-features = false, features = ["float", "std"] } +rug = { git = "https://gitlab.com/tspiteri/rug.git", rev = "96d26fff459cc6be3f6c505a5bc55d14b9ac0222", optional = true, default-features = false, features = ["float", "integer", "std"] } diff --git a/src/math/frexp.rs b/src/math/frexp.rs index badad786a..0c0cd8ed3 100644 --- a/src/math/frexp.rs +++ b/src/math/frexp.rs @@ -1,3 +1,5 @@ +// poke ci + pub fn frexp(x: f64) -> (f64, i32) { let mut y = x.to_bits(); let ee = ((y >> 52) & 0x7ff) as i32; diff --git a/src/math/frexpf.rs b/src/math/frexpf.rs index 2919c0ab0..779740c40 100644 --- a/src/math/frexpf.rs +++ b/src/math/frexpf.rs @@ -1,3 +1,5 @@ +// poke ci + pub fn frexpf(x: f32) -> (f32, i32) { let mut y = x.to_bits(); let ee: i32 = ((y >> 23) & 0xff) as i32; diff --git a/src/math/remquo.rs b/src/math/remquo.rs index 4c11e8487..fea9934e6 100644 --- a/src/math/remquo.rs +++ b/src/math/remquo.rs @@ -1,3 +1,5 @@ +// poke ci + #[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)] pub fn remquo(mut x: f64, mut y: f64) -> (f64, i32) { let ux: u64 = x.to_bits(); diff --git a/src/math/remquof.rs b/src/math/remquof.rs index b0e85ca66..3b178c094 100644 --- a/src/math/remquof.rs +++ b/src/math/remquof.rs @@ -1,3 +1,5 @@ +// poke ci + #[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)] pub fn remquof(mut x: f32, mut y: f32) -> (f32, i32) { let ux: u32 = x.to_bits();