//! Two's complement negation wrapping at 2^384.

use super::U384;

impl U384 {
    /// Computes the two's complement negation `2^384 - self`, wrapping on
    /// overflow (i.e., negating zero returns zero).
    ///
    /// # Examples
    ///
    /// ```
    /// use cnfy_uint::u384::U384;
    ///
    /// assert_eq!(U384::ZERO.negate(), U384::ZERO);
    /// assert_eq!(U384::ONE.negate(), U384::MAX);
    /// ```
    #[inline]
    pub const fn negate(&self) -> U384 {
        U384::ZERO.overflowing_sub(self).0
    }
}

#[cfg(test)]
mod ai_tests {
    use super::*;

    /// Negating zero returns zero.
    #[test]
    fn neg_zero() {
        assert_eq!(U384::ZERO.negate(), U384::ZERO);
    }

    /// Negating one returns MAX.
    #[test]
    fn neg_one() {
        assert_eq!(U384::ONE.negate(), U384::MAX);
    }

    /// Double negation is identity.
    #[test]
    fn double_neg() {
        let a = U384::from_be_limbs([0x1234, 0x5678, 0x9ABC, 0xDEF0, 0x1111, 0x2222]);
        assert_eq!(a.negate().negate(), a);
    }

    /// x + (-x) wraps to zero.
    #[test]
    fn add_neg_is_zero() {
        let a = U384::from_be_limbs([0xAB, 0xCD, 0xEF, 0x42, 0x13, 0x37]);
        let (sum, _) = a.overflowing_add(&a.negate());
        assert_eq!(sum, U384::ZERO);
    }
}
