malachite_nz/integer/logic/
not.rs

1// Copyright © 2025 Mikhail Hogrefe
2//
3// This file is part of Malachite.
4//
5// Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU
6// Lesser General Public License (LGPL) as published by the Free Software Foundation; either version
7// 3 of the License, or (at your option) any later version. See <https://www.gnu.org/licenses/>.
8
9use crate::integer::Integer;
10use crate::natural::Natural;
11use core::ops::Not;
12use malachite_base::num::basic::traits::One;
13use malachite_base::num::logic::traits::NotAssign;
14
15impl Not for Integer {
16    type Output = Self;
17
18    /// Returns the bitwise negation of an [`Integer`], taking it by value.
19    ///
20    /// $$
21    /// f(n) = -n - 1.
22    /// $$
23    ///
24    /// # Worst-case complexity
25    /// $T(n) = O(n)$
26    ///
27    /// $M(n) = O(1)$
28    ///
29    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
30    ///
31    /// # Examples
32    /// ```
33    /// use malachite_base::num::basic::traits::Zero;
34    /// use malachite_nz::integer::Integer;
35    ///
36    /// assert_eq!(!Integer::ZERO, -1);
37    /// assert_eq!(!Integer::from(123), -124);
38    /// assert_eq!(!Integer::from(-123), 122);
39    /// ```
40    #[inline]
41    fn not(mut self) -> Self {
42        self.not_assign();
43        self
44    }
45}
46
47impl Not for &Integer {
48    type Output = Integer;
49
50    /// Returns the bitwise negation of an [`Integer`], taking it by reference.
51    ///
52    /// $$
53    /// f(n) = -n - 1.
54    /// $$
55    ///
56    /// # Worst-case complexity
57    /// $T(n) = O(n)$
58    ///
59    /// $M(n) = O(n)$
60    ///
61    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
62    ///
63    /// # Examples
64    /// ```
65    /// use malachite_base::num::basic::traits::Zero;
66    /// use malachite_nz::integer::Integer;
67    ///
68    /// assert_eq!(!&Integer::ZERO, -1);
69    /// assert_eq!(!&Integer::from(123), -124);
70    /// assert_eq!(!&Integer::from(-123), 122);
71    /// ```
72    fn not(self) -> Integer {
73        match self {
74            Integer { sign: true, abs } => Integer {
75                sign: false,
76                abs: abs.add_limb_ref(1),
77            },
78            Integer { sign: false, abs } => Integer {
79                sign: true,
80                abs: abs.sub_limb_ref(1),
81            },
82        }
83    }
84}
85
86impl NotAssign for Integer {
87    /// Replaces an [`Integer`] with its bitwise negation.
88    ///
89    /// $$
90    /// n \gets -n - 1.
91    /// $$
92    ///
93    /// # Worst-case complexity
94    /// $T(n) = O(n)$
95    ///
96    /// $M(n) = O(1)$
97    ///
98    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
99    ///
100    /// # Examples
101    /// ```
102    /// use malachite_base::num::basic::traits::Zero;
103    /// use malachite_base::num::logic::traits::NotAssign;
104    /// use malachite_nz::integer::Integer;
105    ///
106    /// let mut x = Integer::ZERO;
107    /// x.not_assign();
108    /// assert_eq!(x, -1);
109    ///
110    /// let mut x = Integer::from(123);
111    /// x.not_assign();
112    /// assert_eq!(x, -124);
113    ///
114    /// let mut x = Integer::from(-123);
115    /// x.not_assign();
116    /// assert_eq!(x, 122);
117    /// ```
118    fn not_assign(&mut self) {
119        if self.sign {
120            self.sign = false;
121            self.abs += Natural::ONE;
122        } else {
123            self.sign = true;
124            self.abs -= Natural::ONE;
125        }
126    }
127}