qfall_math/integer/z/logic/complement.rs
1// Copyright © 2025 Niklas Siemer
2//
3// This file is part of qFALL-math.
4//
5// qFALL-math is free software: you can redistribute it and/or modify it under
6// the terms of the Mozilla Public License Version 2.0 as published by the
7// Mozilla Foundation. See <https://mozilla.org/en-US/MPL/2.0/>.
8
9//! This module contains an implementation to compute the bit-wise complement.
10
11use crate::integer::Z;
12use flint_sys::fmpz::fmpz_complement;
13
14impl Z {
15 /// Outputs the bit-wise complement of `self`.
16 ///
17 /// # Examples
18 /// ```
19 /// use qfall_math::integer::Z;
20 /// let value = Z::from(4);
21 ///
22 /// let complement = value.bit_complement();
23 /// let complement_twice = complement.bit_complement();
24 ///
25 /// assert_eq!(Z::from(-5), complement);
26 /// assert_eq!(value, complement_twice);
27 /// ```
28 pub fn bit_complement(&self) -> Self {
29 let mut out = Z::default();
30 unsafe { fmpz_complement(&mut out.value, &self.value) };
31 out
32 }
33}
34
35#[cfg(test)]
36mod test_bitxor {
37 use super::Z;
38
39 /// Ensures that [`Z::bit_complement`] works as intended for small numbers.
40 #[test]
41 fn small_numbers() {
42 let value_0 = Z::from(12);
43 let value_1 = Z::from(567);
44
45 let com_0 = value_0.bit_complement();
46 let com_1 = value_1.bit_complement();
47 let comcom_0 = com_0.bit_complement();
48 let comcom_1 = com_1.bit_complement();
49
50 assert_eq!(Z::from(-13), com_0);
51 assert_eq!(Z::from(-568), com_1);
52 assert_eq!(value_0, comcom_0);
53 assert_eq!(value_1, comcom_1);
54 }
55
56 /// Ensures that [`Z::bit_complement`] works as intended for large numbers.
57 #[test]
58 fn large_numbers() {
59 let value_0 = Z::from(i64::MAX);
60 let value_1 = Z::from(i64::MIN);
61
62 let com_0 = value_0.bit_complement();
63 let com_1 = value_1.bit_complement();
64 let comcom_0 = com_0.bit_complement();
65 let comcom_1 = com_1.bit_complement();
66
67 assert_eq!(Z::from(i64::MIN), com_0);
68 assert_eq!(Z::from(i64::MAX), com_1);
69 assert_eq!(value_0, comcom_0);
70 assert_eq!(value_1, comcom_1);
71 }
72}