|
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