//! Two's complement negation for [`U320`].
use super::U320;

impl U320 {
    /// Returns the two's complement negation of `self` (modular 2^320).
    ///
    /// Computes `0 - self` using wrapping subtraction. The negation of
    /// zero is zero, and the negation of any other value `v` is
    /// `2^320 - v`.
    ///
    /// # Examples
    ///
    /// ```
    /// use cnfy_uint::u320::U320;
    ///
    /// assert_eq!(U320::ZERO.negate(), U320::ZERO);
    /// assert_eq!(U320::ONE.negate(), U320::MAX);
    /// ```
    #[inline]
    pub const fn negate(&self) -> U320 {
        U320::ZERO.overflowing_sub(self).0
    }
}

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

    /// Negation of zero is zero.
    #[test]
    fn negate_zero() {
        assert_eq!(U320::ZERO.negate(), U320::ZERO);
    }

    /// Negation of one is MAX.
    #[test]
    fn negate_one() {
        assert_eq!(U320::ONE.negate(), U320::MAX);
    }

    /// Negation of MAX is one.
    #[test]
    fn negate_max() {
        assert_eq!(U320::MAX.negate(), U320::ONE);
    }

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

    /// v + negate(v) == 0 (modular arithmetic).
    #[test]
    fn negate_plus_self_is_zero() {
        let v = U320::from_be_limbs([0xAA, 0xBB, 0xCC, 0xDD, 0xEE]);
        assert_eq!(v + v.negate(), U320::ZERO);
    }
}
