|
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 az::Az; |
10 | | -use gmp_mpfr_sys::mpfr::rnd_t; |
11 | 8 | use rug::Assign; |
12 | 9 | pub use rug::Float as MpFloat; |
13 | | -use rug::float::Round; |
| 10 | +use rug::az::{self, Az}; |
14 | 11 | use rug::float::Round::Nearest; |
15 | 12 | use rug::ops::{PowAssignRound, RemAssignRound}; |
16 | 13 |
|
@@ -310,13 +307,8 @@ macro_rules! impl_op_for_ty { |
310 | 307 | } |
311 | 308 |
|
312 | 309 | fn run(this: &mut Self::MpTy, input: Self::RustArgs) -> Self::RustRet { |
313 | | - // Implementation taken from `rug::Float::to_f32_exp`. |
314 | 310 | this.assign(input.0); |
315 | | - let exp = this.get_exp().unwrap_or(0); |
316 | | - if exp != 0 { |
317 | | - *this >>= exp; |
318 | | - } |
319 | | - |
| 311 | + let exp = this.frexp_mut(); |
320 | 312 | (prep_retval::<Self::FTy>(this, Ordering::Equal), exp) |
321 | 313 | } |
322 | 314 | } |
@@ -406,28 +398,20 @@ macro_rules! impl_op_for_ty { |
406 | 398 | } |
407 | 399 |
|
408 | 400 | impl MpOp for crate::op::[<remquo $suffix>]::Routine { |
409 | | - type MpTy = (MpFloat, MpFloat, MpFloat); |
| 401 | + type MpTy = (MpFloat, MpFloat); |
410 | 402 |
|
411 | 403 | fn new_mp() -> Self::MpTy { |
412 | 404 | ( |
413 | 405 | new_mpfloat::<Self::FTy>(), |
414 | 406 | new_mpfloat::<Self::FTy>(), |
415 | | - new_mpfloat::<Self::FTy>() |
416 | 407 | ) |
417 | 408 | } |
418 | 409 |
|
419 | 410 | fn run(this: &mut Self::MpTy, input: Self::RustArgs) -> Self::RustRet { |
420 | 411 | this.0.assign(input.0); |
421 | 412 | this.1.assign(input.1); |
422 | | - let (ord, ql) = mpfr_remquo(&mut this.2, &this.0, &this.1, Nearest); |
423 | | - |
424 | | - // `remquo` integer results are sign-magnitude representation. Transfer the |
425 | | - // sign bit from the long result to the int result. |
426 | | - let clear = !(1 << (c_int::BITS - 1)); |
427 | | - let sign = ((ql >> (c_long::BITS - 1)) as i32) << (c_int::BITS - 1); |
428 | | - let q = (ql as i32) & clear | sign; |
429 | | - |
430 | | - (prep_retval::<Self::FTy>(&mut this.2, ord), q) |
| 413 | + let (ord, q) = this.0.remainder_quo31_round(&this.1, Nearest); |
| 414 | + (prep_retval::<Self::FTy>(&mut this.0, ord), q) |
431 | 415 | } |
432 | 416 | } |
433 | 417 |
|
@@ -552,24 +536,3 @@ impl MpOp for crate::op::nextafterf::Routine { |
552 | 536 | unimplemented!("nextafter does not yet have a MPFR operation"); |
553 | 537 | } |
554 | 538 | } |
555 | | - |
556 | | -/// `rug` does not provide `remquo` so this exposes `mpfr_remquo`. See rug#76. |
557 | | -fn mpfr_remquo(r: &mut MpFloat, x: &MpFloat, y: &MpFloat, round: Round) -> (Ordering, c_long) { |
558 | | - let r = r.as_raw_mut(); |
559 | | - let x = x.as_raw(); |
560 | | - let y = y.as_raw(); |
561 | | - let mut q: c_long = 0; |
562 | | - |
563 | | - let round = match round { |
564 | | - Round::Nearest => rnd_t::RNDN, |
565 | | - Round::Zero => rnd_t::RNDZ, |
566 | | - Round::Up => rnd_t::RNDU, |
567 | | - Round::Down => rnd_t::RNDD, |
568 | | - Round::AwayZero => rnd_t::RNDA, |
569 | | - _ => unreachable!(), |
570 | | - }; |
571 | | - |
572 | | - // SAFETY: mutable and const pointers are valid and do not alias, by Rust's rules. |
573 | | - let ord = unsafe { gmp_mpfr_sys::mpfr::remquo(r, &mut q, x, y, round) }; |
574 | | - (ord.cmp(&0), q) |
575 | | -} |
0 commit comments