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}