num-valid 0.3.3

A robust numerical library providing validated types for real and complex numbers to prevent common floating-point errors like NaN propagation. Features a generic, layered architecture with support for native f64 and optional arbitrary-precision arithmetic.
Documentation
#![deny(rustdoc::broken_intra_doc_links)]

//! In-place negation operations.
//!
//! This module provides the [`NegAssign`] trait for negating a value in place,
//! which is more efficient than creating a new negated value for heap-allocated types.

use duplicate::duplicate_item;
use num::Complex;

//-------------------------------------------------------------
/// Compound negation and assignment.
pub trait NegAssign {
    /// Performs the negation.
    fn neg_assign(&mut self);
}

#[duplicate_item(
    T;
    [f64];
    [Complex<f64>];
)]
/// Compound negation and assignment.
impl NegAssign for T {
    /// Performs the negation of `self`.
    fn neg_assign(&mut self) {
        *self = -*self;
    }
}

//-------------------------------------------------------------

//-------------------------------------------------------------
#[cfg(test)]
mod tests {
    use super::*;
    use num::Complex;

    mod native64 {
        use super::*;

        #[test]
        fn test_neg_assign_f64() {
            let mut value = 1.0_f64;
            value.neg_assign();
            let expected_value = -1.0_f64;
            assert_eq!(value, expected_value);

            let mut value = -2.0_f64;
            value.neg_assign();
            let expected_value = 2.0_f64;
            assert_eq!(value, expected_value);
        }

        #[test]
        fn test_neg_assign_complex_f64() {
            let mut value = Complex::new(1.0, -2.0);
            value.neg_assign();
            let expected_value = Complex::new(-1.0, 2.0);
            assert_eq!(value, expected_value);

            let mut value = Complex::new(-3.0, 4.0);
            value.neg_assign();
            let expected_value = Complex::new(3.0, -4.0);
            assert_eq!(value, expected_value);
        }
    }

    #[cfg(feature = "rug")]
    mod rug53 {
        use super::*;
        use crate::backends::rug::validated::{ComplexRugStrictFinite, RealRugStrictFinite};
        use rug::Float;
        use try_create::TryNew;

        const PRECISION: u32 = 53;

        #[test]
        fn test_neg_assign_real_rug() {
            let mut value =
                RealRugStrictFinite::<PRECISION>::try_new(Float::with_val(PRECISION, 1.0)).unwrap();
            value.neg_assign();
            let expected_value =
                RealRugStrictFinite::<PRECISION>::try_new(Float::with_val(PRECISION, -1.0))
                    .unwrap();
            assert_eq!(value, expected_value);

            let mut value =
                RealRugStrictFinite::<PRECISION>::try_new(Float::with_val(PRECISION, -2.0))
                    .unwrap();
            value.neg_assign();
            let expected_value =
                RealRugStrictFinite::<PRECISION>::try_new(Float::with_val(PRECISION, 2.0)).unwrap();
            assert_eq!(value, expected_value);
        }

        #[test]
        fn test_neg_assign_complex_rug() {
            let mut value = ComplexRugStrictFinite::<PRECISION>::try_new(rug::Complex::with_val(
                PRECISION,
                (
                    Float::with_val(PRECISION, 1.0),
                    Float::with_val(PRECISION, -2.0),
                ),
            ))
            .unwrap();
            value.neg_assign();
            let expected_value =
                ComplexRugStrictFinite::<PRECISION>::try_new(rug::Complex::with_val(
                    PRECISION,
                    (
                        Float::with_val(PRECISION, -1.0),
                        Float::with_val(PRECISION, 2.0),
                    ),
                ))
                .unwrap();
            assert_eq!(value, expected_value);

            let mut value = ComplexRugStrictFinite::<PRECISION>::try_new(rug::Complex::with_val(
                PRECISION,
                (
                    Float::with_val(PRECISION, -3.0),
                    Float::with_val(PRECISION, 4.0),
                ),
            ))
            .unwrap();
            value.neg_assign();
            let expected_value =
                ComplexRugStrictFinite::<PRECISION>::try_new(rug::Complex::with_val(
                    PRECISION,
                    (
                        Float::with_val(PRECISION, 3.0),
                        Float::with_val(PRECISION, -4.0),
                    ),
                ))
                .unwrap();
            assert_eq!(value, expected_value);
        }
    }
}
//-------------------------------------------------------------