use {Assign, Float};
use complex::{OrdComplex, Prec};
use ext::mpc as xmpc;
use float::{self, AssignRound, ParseFloatError, Round, Special, ValidFloat};
use gmp_mpfr_sys::mpc::{self, mpc_t};
use gmp_mpfr_sys::mpfr;
use inner::{Inner, InnerMut};
use ops::NegAssign;
#[cfg(feature = "rand")]
use rand::RandState;
use std::cmp::Ordering;
use std::error::Error;
use std::marker::PhantomData;
use std::mem;
use std::ops::Deref;
use std::os::raw::c_int;
use std::ptr;
pub type Round2 = (Round, Round);
pub type Ordering2 = (Ordering, Ordering);
pub struct Complex {
inner: mpc_t,
}
macro_rules! math_op1_complex {
{
$func:path;
$(#[$attr:meta])*
fn $method:ident($($param:ident: $T:ty),*);
$(#[$attr_mut:meta])*
fn $method_mut:ident;
$(#[$attr_round:meta])*
fn $method_round:ident;
$(#[$attr_ref:meta])*
fn $method_ref:ident -> $Ref:ident;
} => {
math_op1_round! {
Complex, Round2 => Ordering2;
$func, rraw2 => ordering2;
$(#[$attr])*
fn $method($($param: $T),*);
$(#[$attr_mut])*
fn $method_mut;
$(#[$attr_round])*
fn $method_round;
$(#[$attr_ref])*
fn $method_ref -> $Ref;
}
}
}
macro_rules! ref_math_op1_complex {
{
$func:path;
$(#[$attr_ref:meta])*
struct $Ref:ident { $($param:ident: $T:ty),* }
} => {
ref_math_op1_round! {
Complex, Round2 => Ordering2;
$func, rraw2 => ordering2;
$(#[$attr_ref])*
struct $Ref { $($param: $T),* }
}
}
}
macro_rules! math_op1_2_complex {
{
$func:path;
$(#[$attr:meta])*
fn $method:ident($rop:ident $(, $param:ident: $T:ty),*);
$(#[$attr_mut:meta])*
fn $method_mut:ident;
$(#[$attr_round:meta])*
fn $method_round:ident;
$(#[$attr_ref:meta])*
fn $method_ref:ident -> $Ref:ident;
} => {
math_op1_2_round! {
Complex, Round2 => (Ordering2, Ordering2);
$func, rraw2, rraw2 => ordering4;
$(#[$attr])*
fn $method($rop $(, $param: $T)*);
$(#[$attr_mut])*
fn $method_mut;
$(#[$attr_round])*
fn $method_round;
$(#[$attr_ref])*
fn $method_ref -> $Ref;
}
}
}
macro_rules! ref_math_op1_2_complex {
{
$func:path;
$(#[$attr_ref:meta])*
struct $Ref:ident { $($param:ident: $T:ty),* }
} => {
ref_math_op1_2_round! {
Complex, Round2 => (Ordering2, Ordering2);
$func, rraw2, rraw2 => ordering4;
$(#[$attr_ref])*
struct $Ref { $($param: $T),* }
}
}
}
impl Complex {
#[inline]
fn new_nan<P: Prec>(prec: P) -> Complex {
let p = prec.prec();
assert!(
p.0 >= float::prec_min() && p.0 <= float::prec_max()
&& p.1 >= float::prec_min()
&& p.1 <= float::prec_max(),
"precision out of range"
);
unsafe {
let mut c: Complex = mem::uninitialized();
mpc::init3(c.inner_mut(), p.0 as mpfr::prec_t, p.1 as mpfr::prec_t);
c
}
}
#[inline]
pub fn new<P: Prec>(prec: P) -> Complex {
let mut ret = Complex::new_nan(prec);
ret.mut_real().assign(Special::Zero);
ret.mut_imag().assign(Special::Zero);
ret
}
#[inline]
pub fn with_val<P: Prec, T>(prec: P, val: T) -> Complex
where
Complex: Assign<T>,
{
let mut ret = Complex::new_nan(prec);
ret.assign(val);
ret
}
#[inline]
pub fn with_val_round<P: Prec, T>(
prec: P,
val: T,
round: Round2,
) -> (Complex, Ordering2)
where
Complex: AssignRound<T, Round = Round2, Ordering = Ordering2>,
{
let mut ret = Complex::new_nan(prec);
let ord = ret.assign_round(val, round);
(ret, ord)
}
#[inline]
pub fn prec(&self) -> (u32, u32) {
(self.real().prec(), self.imag().prec())
}
#[inline]
pub fn set_prec<P: Prec>(&mut self, prec: P) {
self.set_prec_round(prec, Default::default());
}
#[inline]
pub fn set_prec_round<P: Prec>(
&mut self,
prec: P,
round: Round2,
) -> Ordering2 {
let p = prec.prec();
let (real, imag) = self.as_mut_real_imag();
(
real.set_prec_round(p.0, round.0),
imag.set_prec_round(p.1, round.1),
)
}
#[inline]
pub fn from_str<P: Prec>(
src: &str,
prec: P,
) -> Result<Complex, ParseComplexError> {
let mut val = Complex::new_nan(prec);
val.assign_str(src)?;
Ok(val)
}
#[inline]
pub fn from_str_round<P: Prec>(
src: &str,
prec: P,
round: Round2,
) -> Result<(Complex, Ordering2), ParseComplexError> {
let mut val = Complex::new_nan(prec);
let ord = val.assign_str_round(src, round)?;
Ok((val, ord))
}
#[inline]
pub fn from_str_radix<P: Prec>(
src: &str,
radix: i32,
prec: P,
) -> Result<Complex, ParseComplexError> {
let mut val = Complex::new_nan(prec);
val.assign_str_radix(src, radix)?;
Ok(val)
}
#[inline]
pub fn from_str_radix_round<P: Prec>(
src: &str,
radix: i32,
prec: P,
round: Round2,
) -> Result<(Complex, Ordering2), ParseComplexError> {
let mut val = Complex::new_nan(prec);
let ord = val.assign_str_radix_round(src, radix, round)?;
Ok((val, ord))
}
pub fn valid_str_radix(
src: &str,
radix: i32,
) -> Result<ValidComplex, ParseComplexError> {
use self::ParseComplexError as Error;
use self::ParseErrorKind as Kind;
let p = if src.starts_with('(') {
let space = src.find(' ').ok_or(Error {
kind: Kind::MissingSpace,
})?;
let real_str = &src[1..space];
let re = Float::valid_str_radix(real_str, radix).map_err(|e| {
Error {
kind: Kind::InvalidRealFloat(e),
}
})?;
let rest = &src[space + 1..];
let close = rest.find(')').ok_or(Error {
kind: Kind::MissingClose,
})?;
let imag_str = &rest[0..close];
let im = Float::valid_str_radix(imag_str, radix).map_err(|e| {
Error {
kind: Kind::InvalidImagFloat(e),
}
})?;
if close != rest.len() - 1 {
return Err(Error {
kind: Kind::CloseNotLast,
});
}
ValidPoss::Complex(re, im)
} else {
let re = Float::valid_str_radix(src, radix).map_err(|e| {
Error {
kind: Kind::InvalidFloat(e),
}
})?;
ValidPoss::Real(re)
};
Ok(ValidComplex { poss: p })
}
#[inline]
pub fn to_string_radix(
&self,
radix: i32,
num_digits: Option<usize>,
) -> String {
self.to_string_radix_round(radix, num_digits, Default::default())
}
pub fn to_string_radix_round(
&self,
radix: i32,
num_digits: Option<usize>,
round: Round2,
) -> String {
let mut buf = String::from("(");
buf += &self.real()
.to_string_radix_round(radix, num_digits, round.0);
buf.push(' ');
buf += &self.imag()
.to_string_radix_round(radix, num_digits, round.0);
buf.push(')');
buf
}
#[inline]
pub fn assign_str(&mut self, src: &str) -> Result<(), ParseComplexError> {
self.assign_str_radix(src, 10)
}
#[inline]
pub fn assign_str_round(
&mut self,
src: &str,
round: Round2,
) -> Result<Ordering2, ParseComplexError> {
self.assign_str_radix_round(src, 10, round)
}
#[inline]
pub fn assign_str_radix(
&mut self,
src: &str,
radix: i32,
) -> Result<(), ParseComplexError> {
self.assign_str_radix_round(src, radix, Default::default())
.map(|_| ())
}
#[inline]
pub fn assign_str_radix_round(
&mut self,
src: &str,
radix: i32,
round: Round2,
) -> Result<Ordering2, ParseComplexError> {
Ok(self.assign_round(
Complex::valid_str_radix(src, radix)?,
round,
))
}
#[inline]
pub fn real(&self) -> &Float {
unsafe {
let ptr = mpc::realref_const(self.inner());
&*(ptr as *const Float)
}
}
#[inline]
pub fn imag(&self) -> &Float {
unsafe {
let ptr = mpc::imagref_const(self.inner());
&*(ptr as *const Float)
}
}
#[inline]
pub fn mut_real(&mut self) -> &mut Float {
unsafe {
let ptr = mpc::realref(self.inner_mut());
&mut *(ptr as *mut Float)
}
}
#[inline]
pub fn mut_imag(&mut self) -> &mut Float {
unsafe {
let ptr = mpc::imagref(self.inner_mut());
&mut *(ptr as *mut Float)
}
}
#[inline]
pub fn as_real_imag(&self) -> (&Float, &Float) {
(self.real(), self.imag())
}
#[inline]
pub fn as_mut_real_imag(&mut self) -> (&mut Float, &mut Float) {
unsafe {
let real_ptr = mpc::realref(self.inner_mut());
let imag_ptr = mpc::imagref(self.inner_mut());
(
&mut *(real_ptr as *mut Float),
&mut *(imag_ptr as *mut Float),
)
}
}
#[inline]
pub fn into_real_imag(mut self) -> (Float, Float) {
let (mut real, mut imag) = unsafe { mem::uninitialized() };
unsafe {
let real_imag = self.as_mut_real_imag();
ptr::copy_nonoverlapping(real_imag.0, &mut real, 1);
ptr::copy_nonoverlapping(real_imag.1, &mut imag, 1);
}
mem::forget(self);
(real, imag)
}
pub fn as_neg(&self) -> BorrowComplex {
let mut ret = BorrowComplex {
inner: self.inner,
phantom: PhantomData,
};
let (self_re, self_im) = self.as_real_imag();
unsafe {
if self_re.is_nan() {
mpfr::set_nanflag();
} else {
(*mpc::realref(&mut ret.inner)).sign.neg_assign();
}
if self_im.is_nan() {
mpfr::set_nanflag();
} else {
(*mpc::imagref(&mut ret.inner)).sign.neg_assign();
}
}
ret
}
pub fn as_conj(&self) -> BorrowComplex {
let mut ret = BorrowComplex {
inner: self.inner,
phantom: PhantomData,
};
let self_im = self.imag();
unsafe {
if self_im.is_nan() {
mpfr::set_nanflag();
} else {
(*mpc::imagref(&mut ret.inner)).sign.neg_assign();
}
}
ret
}
pub fn as_mul_i(&self, negative: bool) -> BorrowComplex {
let (self_re, self_im) = self.as_real_imag();
let (self_re_nan, self_im_nan) = (self_re.is_nan(), self_im.is_nan());
let (self_re, self_im) = (self_re.inner(), self_im.inner());
let mut ret = BorrowComplex {
inner: unsafe { mem::uninitialized() },
phantom: PhantomData,
};
let (ret_re, ret_im) = unsafe {
let re = &mut *mpc::realref(&mut ret.inner);
let im = &mut *mpc::imagref(&mut ret.inner);
(re, im)
};
*ret_re = *self_im;
*ret_im = *self_re;
unsafe {
if negative {
if self_re_nan {
mpfr::set_nanflag();
} else {
ret_im.sign.neg_assign();
}
} else if self_im_nan {
mpfr::set_nanflag();
} else {
ret_re.sign.neg_assign();
}
}
ret
}
pub fn as_ord(&self) -> &OrdComplex {
unsafe { &*(self as *const _ as *const _) }
}
math_op1_no_round! {
Complex;
mpc::proj, rraw2;
fn proj();
fn proj_mut;
fn proj_ref -> ProjRef;
}
math_op1_complex! {
mpc::sqr;
fn square();
fn square_mut;
fn square_round;
fn square_ref -> SquareRef;
}
math_op1_complex! {
mpc::sqrt;
fn sqrt();
fn sqrt_mut;
fn sqrt_round;
fn sqrt_ref -> SqrtRef;
}
math_op1_no_round! {
Complex;
mpc::conj, rraw2;
fn conj();
fn conj_mut;
fn conj_ref -> ConjugateRef;
}
#[inline]
pub fn abs(self) -> Float {
let (mut re, im) = self.into_real_imag();
re.hypot_mut(&im);
re
}
#[inline]
pub fn abs_mut(&mut self) {
let (re, im) = self.as_mut_real_imag();
re.hypot_mut(im);
im.assign(Special::Zero);
}
#[inline]
pub fn abs_ref(&self) -> AbsRef {
AbsRef { ref_self: self }
}
#[inline]
pub fn arg(self) -> Float {
let (mut re, im) = self.into_real_imag();
unsafe {
mpfr::atan2(
re.inner_mut(),
im.inner(),
re.inner(),
rraw(Round::Nearest),
);
}
re
}
#[inline]
pub fn arg_mut(&mut self) {
self.arg_round(Default::default());
}
#[inline]
pub fn arg_round(&mut self, round: Round2) -> Ordering2 {
let (re, im) = self.as_mut_real_imag();
let ret = unsafe {
mpfr::atan2(re.inner_mut(), im.inner(), re.inner(), rraw(round.0))
};
let dir_re = ordering1(ret);
let dir_im = im.assign_round(Special::Zero, round.1);
(dir_re, dir_im)
}
#[inline]
pub fn arg_ref(&self) -> ArgRef {
ArgRef { ref_self: self }
}
math_op1_complex! {
xmpc::mul_i;
fn mul_i(negative: bool);
fn mul_i_mut;
fn mul_i_round;
fn mul_i_ref -> MulIRef;
}
math_op1_complex! {
xmpc::recip;
fn recip();
fn recip_mut;
fn recip_round;
fn recip_ref -> RecipRef;
}
#[inline]
pub fn norm(self) -> Float {
Float::with_val(self.real().prec(), self.norm_ref())
}
#[inline]
pub fn norm_mut(&mut self) {
self.norm_round(Default::default());
}
#[inline]
pub fn norm_round(&mut self, round: Round2) -> Ordering2 {
let (norm, dir_re) =
Float::with_val_round(self.real().prec(), self.norm_ref(), round.0);
let (real, imag) = self.as_mut_real_imag();
mem::replace(real, norm);
let dir_im = imag.assign_round(Special::Zero, round.1);
(dir_re, dir_im)
}
#[inline]
pub fn norm_ref(&self) -> NormRef {
NormRef { ref_self: self }
}
math_op1_complex! {
mpc::log;
fn ln();
fn ln_mut;
fn ln_round;
fn ln_ref -> LnRef;
}
math_op1_complex! {
mpc::log10;
fn log10();
fn log10_mut;
fn log10_round;
fn log10_ref -> Log10Ref;
}
math_op1_complex! {
mpc::exp;
fn exp();
fn exp_mut;
fn exp_round;
fn exp_ref -> ExpRef;
}
math_op1_complex! {
mpc::sin;
fn sin();
fn sin_mut;
fn sin_round;
fn sin_ref -> SinRef;
}
math_op1_complex! {
mpc::cos;
fn cos();
fn cos_mut;
fn cos_round;
fn cos_ref -> CosRef;
}
math_op1_2_complex! {
mpc::sin_cos;
fn sin_cos(cos);
fn sin_cos_mut;
fn sin_cos_round;
fn sin_cos_ref -> SinCosRef;
}
math_op1_complex! {
mpc::tan;
fn tan();
fn tan_mut;
fn tan_round;
fn tan_ref -> TanRef;
}
math_op1_complex! {
mpc::sinh;
fn sinh();
fn sinh_mut;
fn sinh_round;
fn sinh_ref -> SinhRef;
}
math_op1_complex! {
mpc::cosh;
fn cosh();
fn cosh_mut;
fn cosh_round;
fn cosh_ref -> CoshRef;
}
math_op1_complex! {
mpc::tanh;
fn tanh();
fn tanh_mut;
fn tanh_round;
fn tanh_ref -> TanhRef;
}
math_op1_complex! {
mpc::asin;
fn asin();
fn asin_mut;
fn asin_round;
fn asin_ref -> AsinRef;
}
math_op1_complex! {
mpc::acos;
fn acos();
fn acos_mut;
fn acos_round;
fn acos_ref -> AcosRef;
}
math_op1_complex! {
mpc::atan;
fn atan();
fn atan_mut;
fn atan_round;
fn atan_ref -> AtanRef;
}
math_op1_complex! {
mpc::asinh;
fn asinh();
fn asinh_mut;
fn asinh_round;
fn asinh_ref -> AsinhRef;
}
math_op1_complex! {
mpc::acosh;
fn acosh();
fn acosh_mut;
fn acosh_round;
fn acosh_ref -> AcoshRef;
}
math_op1_complex! {
mpc::atanh;
fn atanh();
fn atanh_mut;
fn atanh_round;
fn atanh_ref -> AtanhRef;
}
#[cfg(feature = "rand")]
#[inline]
pub fn assign_random_bits(
&mut self,
rng: &mut RandState,
) -> Result<(), ()> {
let (real, imag) = self.as_mut_real_imag();
real.assign_random_bits(rng)?;
imag.assign_random_bits(rng)
}
#[cfg(feature = "rand")]
#[inline]
pub fn assign_random_cont(&mut self, rng: &mut RandState) {
self.assign_random_cont_round(rng, Default::default());
}
#[cfg(feature = "rand")]
#[inline]
pub fn assign_random_cont_round(
&mut self,
rng: &mut RandState,
round: Round2,
) -> Ordering2 {
let (real, imag) = self.as_mut_real_imag();
(
real.assign_random_cont_round(rng, round.0),
imag.assign_random_cont_round(rng, round.1),
)
}
}
ref_math_op1_complex! { mpc::proj; struct ProjRef {} }
ref_math_op1_complex! { mpc::sqr; struct SquareRef {} }
ref_math_op1_complex! { mpc::sqrt; struct SqrtRef {} }
ref_math_op1_complex! { mpc::conj; struct ConjugateRef {} }
pub struct AbsRef<'a> {
ref_self: &'a Complex,
}
impl<'a> AssignRound<AbsRef<'a>> for Float {
type Round = Round;
type Ordering = Ordering;
#[inline]
fn assign_round(&mut self, src: AbsRef<'a>, round: Round) -> Ordering {
let ret = unsafe {
mpc::abs(self.inner_mut(), src.ref_self.inner(), rraw(round))
};
ret.cmp(&0)
}
}
pub struct ArgRef<'a> {
ref_self: &'a Complex,
}
impl<'a> AssignRound<ArgRef<'a>> for Float {
type Round = Round;
type Ordering = Ordering;
#[inline]
fn assign_round(&mut self, src: ArgRef<'a>, round: Round) -> Ordering {
let ret = unsafe {
mpc::arg(self.inner_mut(), src.ref_self.inner(), rraw(round))
};
ret.cmp(&0)
}
}
ref_math_op1_complex! { xmpc::mul_i; struct MulIRef { negative: bool } }
ref_math_op1_complex! { xmpc::recip; struct RecipRef {} }
pub struct NormRef<'a> {
ref_self: &'a Complex,
}
impl<'a> AssignRound<NormRef<'a>> for Float {
type Round = Round;
type Ordering = Ordering;
#[inline]
fn assign_round(&mut self, src: NormRef<'a>, round: Round) -> Ordering {
let ret = unsafe {
mpc::norm(self.inner_mut(), src.ref_self.inner(), rraw(round))
};
ret.cmp(&0)
}
}
ref_math_op1_complex! { mpc::log; struct LnRef {} }
ref_math_op1_complex! { mpc::log10; struct Log10Ref {} }
ref_math_op1_complex! { mpc::exp; struct ExpRef {} }
ref_math_op1_complex! { mpc::sin; struct SinRef {} }
ref_math_op1_complex! { mpc::cos; struct CosRef {} }
ref_math_op1_2_complex! { mpc::sin_cos; struct SinCosRef {} }
ref_math_op1_complex! { mpc::tan; struct TanRef {} }
ref_math_op1_complex! { mpc::sinh; struct SinhRef {} }
ref_math_op1_complex! { mpc::cosh; struct CoshRef {} }
ref_math_op1_complex! { mpc::tanh; struct TanhRef {} }
ref_math_op1_complex! { mpc::asin; struct AsinRef {} }
ref_math_op1_complex! { mpc::acos; struct AcosRef {} }
ref_math_op1_complex! { mpc::atan; struct AtanRef {} }
ref_math_op1_complex! { mpc::asinh; struct AsinhRef {} }
ref_math_op1_complex! { mpc::acosh; struct AcoshRef {} }
ref_math_op1_complex! { mpc::atanh; struct AtanhRef {} }
#[derive(Clone, Copy)]
pub struct BorrowComplex<'a> {
inner: mpc_t,
phantom: PhantomData<&'a Complex>,
}
impl<'a> Deref for BorrowComplex<'a> {
type Target = Complex;
#[inline]
fn deref(&self) -> &Complex {
let ptr = (&self.inner) as *const _ as *const _;
unsafe { &*ptr }
}
}
#[derive(Clone, Debug)]
pub struct ValidComplex<'a> {
poss: ValidPoss<'a>,
}
#[derive(Clone, Debug)]
enum ValidPoss<'a> {
Real(ValidFloat<'a>),
Complex(ValidFloat<'a>, ValidFloat<'a>),
}
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct ParseComplexError {
kind: ParseErrorKind,
}
impl<'a> AssignRound<ValidComplex<'a>> for Complex {
type Round = Round2;
type Ordering = Ordering2;
#[inline]
fn assign_round(&mut self, rhs: ValidComplex, round: Round2) -> Ordering2 {
match rhs.poss {
ValidPoss::Real(re) => {
let real_ord = self.mut_real().assign_round(re, round.0);
self.mut_imag().assign(Special::Zero);
(real_ord, Ordering::Equal)
}
ValidPoss::Complex(re, im) => {
let real_ord = self.mut_real().assign_round(re, round.0);
let imag_ord = self.mut_imag().assign_round(im, round.1);
(real_ord, imag_ord)
}
}
}
}
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
enum ParseErrorKind {
InvalidFloat(ParseFloatError),
InvalidRealFloat(ParseFloatError),
InvalidImagFloat(ParseFloatError),
MissingSpace,
MissingClose,
CloseNotLast,
}
impl Error for ParseComplexError {
fn description(&self) -> &str {
use self::ParseErrorKind::*;
match self.kind {
InvalidFloat(_) => "string is not a valid float",
InvalidRealFloat(_) => "real part of string is not a valid float",
InvalidImagFloat(_) => {
"imaginary part of string is not a valid float"
}
MissingSpace => "string has no space after opening bracket",
MissingClose => "string has no closing bracket",
CloseNotLast => "string has more characters after closing bracket",
}
}
}
#[inline]
fn rraw(round: Round) -> mpfr::rnd_t {
match round {
Round::Nearest => mpfr::rnd_t::RNDN,
Round::Zero => mpfr::rnd_t::RNDZ,
Round::Up => mpfr::rnd_t::RNDU,
Round::Down => mpfr::rnd_t::RNDD,
Round::AwayFromZero => mpfr::rnd_t::RNDA,
}
}
#[inline]
pub fn rraw2(round: Round2) -> mpc::rnd_t {
match (round.0, round.1) {
(Round::Nearest, Round::Nearest) => mpc::RNDNN,
(Round::Nearest, Round::Zero) => mpc::RNDNZ,
(Round::Nearest, Round::Up) => mpc::RNDNU,
(Round::Nearest, Round::Down) => mpc::RNDND,
(Round::Zero, Round::Nearest) => mpc::RNDZN,
(Round::Zero, Round::Zero) => mpc::RNDZZ,
(Round::Zero, Round::Up) => mpc::RNDZU,
(Round::Zero, Round::Down) => mpc::RNDZD,
(Round::Up, Round::Nearest) => mpc::RNDUN,
(Round::Up, Round::Zero) => mpc::RNDUZ,
(Round::Up, Round::Up) => mpc::RNDUU,
(Round::Up, Round::Down) => mpc::RNDUD,
(Round::Down, Round::Nearest) => mpc::RNDDN,
(Round::Down, Round::Zero) => mpc::RNDDZ,
(Round::Down, Round::Up) => mpc::RNDDU,
(Round::Down, Round::Down) => mpc::RNDDD,
(Round::AwayFromZero, _) | (_, Round::AwayFromZero) => unimplemented!(),
}
}
#[inline]
fn ordering1(ord: c_int) -> Ordering {
ord.cmp(&0)
}
#[inline]
pub fn ordering2(ord: c_int) -> Ordering2 {
let first = mpc::INEX_RE(ord).cmp(&0);
let second = mpc::INEX_IM(ord).cmp(&0);
(first, second)
}
#[inline]
fn ordering4(ord: c_int) -> (Ordering2, Ordering2) {
(ordering2(mpc::INEX1(ord)), ordering2(mpc::INEX2(ord)))
}
impl Inner for Complex {
type Output = mpc_t;
#[inline]
fn inner(&self) -> &mpc_t {
&self.inner
}
}
impl InnerMut for Complex {
#[inline]
unsafe fn inner_mut(&mut self) -> &mut mpc_t {
&mut self.inner
}
}