oxinum-complex 0.1.0

Arbitrary-precision complex numbers for OxiNum (CBig over DBig; Pure Rust, GMP/MPFR-free)
Documentation
//! Conversions between native [`BigComplex`] and other numeric types.
//!
//! Provides the infallible `From` constructors for the ordered `(re, im)`
//! [`BigFloat`] pair and for a purely-real [`BigFloat`] (placed on the real
//! axis, `im = 0` at the real part's precision), plus a lossy projection to a
//! pair of `f64`s via [`BigFloat::to_f64`].

use oxinum_float::native::BigFloat;

use super::BigComplex;

impl From<(BigFloat, BigFloat)> for BigComplex {
    /// Build `re + im·i` from the ordered pair `(re, im)`.
    #[inline]
    fn from((re, im): (BigFloat, BigFloat)) -> Self {
        BigComplex::from_parts(re, im)
    }
}

impl From<BigFloat> for BigComplex {
    /// Place a real [`BigFloat`] on the real axis (`im = 0` at `re`'s precision).
    #[inline]
    fn from(re: BigFloat) -> Self {
        BigComplex::from_real(re)
    }
}

impl BigComplex {
    /// Project to a pair of `f64`s `(re, im)` via [`BigFloat::to_f64`].
    ///
    /// This is a lossy convenience conversion: each component is rounded to the
    /// nearest `f64` (and non-finite components map to the corresponding
    /// `f64::NAN` / `f64::INFINITY`, matching `BigFloat::to_f64`).
    ///
    /// # Examples
    ///
    /// ```
    /// use oxinum_complex::native::BigComplex;
    /// let z = BigComplex::from_f64(1.5, -2.25, 80).expect("finite");
    /// let (re, im) = z.to_f64_parts();
    /// assert_eq!(re, 1.5);
    /// assert_eq!(im, -2.25);
    /// ```
    pub fn to_f64_parts(&self) -> (f64, f64) {
        (self.re().to_f64(), self.im().to_f64())
    }
}

// ---------------------------------------------------------------------------
// Tests
// ---------------------------------------------------------------------------

#[cfg(test)]
mod tests {
    use super::*;
    use oxinum_float::native::RoundingMode;

    #[test]
    fn from_pair() {
        let re = BigFloat::from_f64(2.0, 80).expect("re");
        let im = BigFloat::from_f64(-3.0, 80).expect("im");
        let z = BigComplex::from((re, im));
        assert_eq!(z.re().to_f64(), 2.0);
        assert_eq!(z.im().to_f64(), -3.0);
    }

    #[test]
    fn from_real_axis() {
        let re = BigFloat::from_i64(7, 80, RoundingMode::HalfEven);
        let z = BigComplex::from(re);
        assert_eq!(z.re().to_f64(), 7.0);
        assert!(z.im().is_zero());
    }

    #[test]
    fn to_f64_parts_roundtrip() {
        let z = BigComplex::from_f64(1.5, -2.25, 80).expect("finite");
        let (re, im) = z.to_f64_parts();
        assert_eq!(re, 1.5);
        assert_eq!(im, -2.25);
    }
}