Skip to content
This repository was archived by the owner on Apr 28, 2025. It is now read-only.

Commit 0f6b1bb

Browse files
committed
Add tests against MPFR for remquo and remquof
Rug does not yet expose this function, but it is possible to use the MPFR bindings directly.
1 parent 8e82616 commit 0f6b1bb

File tree

4 files changed

+51
-9
lines changed

4 files changed

+51
-9
lines changed

crates/libm-test/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ paste = "1.0.15"
3535
rand = "0.8.5"
3636
rand_chacha = "0.3.1"
3737
rayon = "1.10.0"
38-
rug = { version = "1.26.1", optional = true, default-features = false, features = ["float", "std"] }
38+
rug = { version = "1.26.1", optional = true, default-features = false, features = ["float", "integer", "std"] }
3939

4040
[target.'cfg(target_family = "wasm")'.dependencies]
4141
# Enable randomness on WASM

crates/libm-test/src/mpfloat.rs

+50
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,13 @@
44
//! a struct named `Operation` that implements [`MpOp`].
55
66
use std::cmp::Ordering;
7+
use std::ffi::{c_int, c_long};
78

89
use az::Az;
10+
use gmp_mpfr_sys::mpfr::rnd_t;
911
use rug::Assign;
1012
pub use rug::Float as MpFloat;
13+
use rug::float::Round;
1114
use rug::float::Round::Nearest;
1215
use rug::ops::{PowAssignRound, RemAssignRound};
1316

@@ -361,6 +364,32 @@ macro_rules! impl_op_for_ty {
361364
}
362365
}
363366

367+
impl MpOp for crate::op::[<remquo $suffix>]::Routine {
368+
type MpTy = (MpFloat, MpFloat, MpFloat);
369+
370+
fn new_mp() -> Self::MpTy {
371+
(
372+
new_mpfloat::<Self::FTy>(),
373+
new_mpfloat::<Self::FTy>(),
374+
new_mpfloat::<Self::FTy>()
375+
)
376+
}
377+
378+
fn run(this: &mut Self::MpTy, input: Self::RustArgs) -> Self::RustRet {
379+
this.0.assign(input.0);
380+
this.1.assign(input.1);
381+
let (ord, ql) = mpfr_remquo(&mut this.2, &this.0, &this.1, Nearest);
382+
383+
// `remquo` integer results are sign-magnitude representation. Transfer the
384+
// sign bit from the long result to the int result.
385+
let clear = !(1 << (c_int::BITS - 1));
386+
let sign = ((ql >> (c_long::BITS - 1)) as i32) << (c_int::BITS - 1);
387+
let q = (ql as i32) & clear | sign;
388+
389+
(prep_retval::<Self::FTy>(&mut this.2, ord), q)
390+
}
391+
}
392+
364393
impl MpOp for crate::op::[<yn $suffix>]::Routine {
365394
type MpTy = MpFloat;
366395

@@ -441,3 +470,24 @@ impl MpOp for crate::op::lgammaf_r::Routine {
441470
(ret, sign as i32)
442471
}
443472
}
473+
474+
/// `rug` does not provide `remquo` so this exposes `mpfr_remquo`. See rug#76.
475+
fn mpfr_remquo(r: &mut MpFloat, x: &MpFloat, y: &MpFloat, round: Round) -> (Ordering, c_long) {
476+
let r = r.as_raw_mut();
477+
let x = x.as_raw();
478+
let y = y.as_raw();
479+
let mut q: c_long = 0;
480+
481+
let round = match round {
482+
Round::Nearest => rnd_t::RNDN,
483+
Round::Zero => rnd_t::RNDZ,
484+
Round::Up => rnd_t::RNDU,
485+
Round::Down => rnd_t::RNDD,
486+
Round::AwayZero => rnd_t::RNDA,
487+
_ => unreachable!(),
488+
};
489+
490+
// SAFETY: mutable and const pointers are valid and do not alias, by Rust's rules.
491+
let ord = unsafe { gmp_mpfr_sys::mpfr::remquo(r, &mut q, x, y, round) };
492+
(ord.cmp(&0), q)
493+
}

crates/libm-test/tests/multiprecision.rs

-4
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,6 @@ libm_macros::for_each_function! {
5050
[jn, jnf, yn, ynf],
5151
],
5252
skip: [
53-
// FIXME: MPFR tests needed
54-
remquo,
55-
remquof,
56-
5753
// FIXME: test needed, see
5854
// https://github.com/rust-lang/libm/pull/311#discussion_r1818273392
5955
nextafter,

crates/libm-test/tests/z_extensive/run.rs

-4
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,6 @@ fn register_all_tests() -> Vec<Trial> {
4848
callback: mp_extensive_tests,
4949
extra: [all_tests],
5050
skip: [
51-
// FIXME: MPFR tests needed
52-
remquo,
53-
remquof,
54-
5551
// FIXME: test needed, see
5652
// https://github.com/rust-lang/libm/pull/311#discussion_r1818273392
5753
nextafter,

0 commit comments

Comments
 (0)