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}