|
4 | 4 | //! a struct named `Operation` that implements [`MpOp`]. |
5 | 5 |
|
6 | 6 | use std::cmp::Ordering; |
7 | | -use std::ffi::{c_int, c_long}; |
8 | 7 |
|
9 | | -use gmp_mpfr_sys::mpfr::rnd_t; |
10 | 8 | use rug::Assign; |
11 | 9 | pub use rug::Float as MpFloat; |
12 | 10 | use rug::az::{self, Az}; |
13 | | -use rug::float::Round; |
14 | 11 | use rug::float::Round::Nearest; |
15 | 12 | use rug::ops::{PowAssignRound, RemAssignRound}; |
16 | 13 |
|
@@ -410,28 +407,20 @@ macro_rules! impl_op_for_ty { |
410 | 407 | } |
411 | 408 |
|
412 | 409 | impl MpOp for crate::op::[<remquo $suffix>]::Routine { |
413 | | - type MpTy = (MpFloat, MpFloat, MpFloat); |
| 410 | + type MpTy = (MpFloat, MpFloat); |
414 | 411 |
|
415 | 412 | fn new_mp() -> Self::MpTy { |
416 | 413 | ( |
417 | 414 | new_mpfloat::<Self::FTy>(), |
418 | 415 | new_mpfloat::<Self::FTy>(), |
419 | | - new_mpfloat::<Self::FTy>() |
420 | 416 | ) |
421 | 417 | } |
422 | 418 |
|
423 | 419 | fn run(this: &mut Self::MpTy, input: Self::RustArgs) -> Self::RustRet { |
424 | 420 | this.0.assign(input.0); |
425 | 421 | this.1.assign(input.1); |
426 | | - let (ord, ql) = mpfr_remquo(&mut this.2, &this.0, &this.1, Nearest); |
427 | | - |
428 | | - // `remquo` integer results are sign-magnitude representation. Transfer the |
429 | | - // sign bit from the long result to the int result. |
430 | | - let clear = !(1 << (c_int::BITS - 1)); |
431 | | - let sign = ((ql >> (c_long::BITS - 1)) as i32) << (c_int::BITS - 1); |
432 | | - let q = (ql as i32) & clear | sign; |
433 | | - |
434 | | - (prep_retval::<Self::FTy>(&mut this.2, ord), q) |
| 422 | + let (ord, q) = this.0.remainder_quo31_round(&this.1, Nearest); |
| 423 | + (prep_retval::<Self::FTy>(&mut this.0, ord), q) |
435 | 424 | } |
436 | 425 | } |
437 | 426 |
|
@@ -541,24 +530,3 @@ impl MpOp for crate::op::nextafterf::Routine { |
541 | 530 | unimplemented!("nextafter does not yet have a MPFR operation"); |
542 | 531 | } |
543 | 532 | } |
544 | | - |
545 | | -/// `rug` does not provide `remquo` so this exposes `mpfr_remquo`. See rug#76. |
546 | | -fn mpfr_remquo(r: &mut MpFloat, x: &MpFloat, y: &MpFloat, round: Round) -> (Ordering, c_long) { |
547 | | - let r = r.as_raw_mut(); |
548 | | - let x = x.as_raw(); |
549 | | - let y = y.as_raw(); |
550 | | - let mut q: c_long = 0; |
551 | | - |
552 | | - let round = match round { |
553 | | - Round::Nearest => rnd_t::RNDN, |
554 | | - Round::Zero => rnd_t::RNDZ, |
555 | | - Round::Up => rnd_t::RNDU, |
556 | | - Round::Down => rnd_t::RNDD, |
557 | | - Round::AwayZero => rnd_t::RNDA, |
558 | | - _ => unreachable!(), |
559 | | - }; |
560 | | - |
561 | | - // SAFETY: mutable and const pointers are valid and do not alias, by Rust's rules. |
562 | | - let ord = unsafe { gmp_mpfr_sys::mpfr::remquo(r, &mut q, x, y, round) }; |
563 | | - (ord.cmp(&0), q) |
564 | | -} |
0 commit comments