Skip to main content

malachite_nz/gaussian_integer/logic/
significant_bits.rs

1// Copyright © 2026 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::gaussian_integer::GaussianInteger;
10use malachite_base::num::logic::traits::SignificantBits;
11
12impl GaussianInteger {
13    /// Returns the larger of the numbers of significant bits of the real and imaginary parts of a
14    /// [`GaussianInteger`], each taken in absolute value.
15    ///
16    /// This is the size measure that FLINT's `fmpzi_bits` computes, and the one that the sizes of
17    /// the parts are compared against when an algorithm is chosen; the [`SignificantBits`]
18    /// implementation sums the two counts instead.
19    ///
20    /// $$
21    /// f(a + bi) = \max(\operatorname{bits}(a), \operatorname{bits}(b)),
22    /// $$
23    /// where $\operatorname{bits}(n)$ is the number of significant bits of $|n|$, with
24    /// $\operatorname{bits}(0) = 0$.
25    ///
26    /// # Worst-case complexity
27    /// Constant time and additional memory.
28    ///
29    /// # Examples
30    /// ```
31    /// use malachite_base::num::basic::traits::Zero;
32    /// use malachite_nz::gaussian_integer::GaussianInteger;
33    /// use std::str::FromStr;
34    ///
35    /// assert_eq!(GaussianInteger::ZERO.max_significant_bits(), 0);
36    /// assert_eq!(
37    ///     GaussianInteger::from_str("3+4i")
38    ///         .unwrap()
39    ///         .max_significant_bits(),
40    ///     3
41    /// );
42    /// assert_eq!(
43    ///     GaussianInteger::from_str("1000000000000+i")
44    ///         .unwrap()
45    ///         .max_significant_bits(),
46    ///     40
47    /// );
48    /// ```
49    #[inline]
50    pub fn max_significant_bits(&self) -> u64 {
51        self.real
52            .significant_bits()
53            .max(self.imaginary.significant_bits())
54    }
55}
56
57impl SignificantBits for &GaussianInteger {
58    /// Returns the sum of the numbers of significant bits of the real and imaginary parts of a
59    /// [`GaussianInteger`], each taken in absolute value.
60    ///
61    /// $$
62    /// f(a + bi) = \operatorname{bits}(a) + \operatorname{bits}(b),
63    /// $$
64    /// where $\operatorname{bits}(n)$ is the number of significant bits of $|n|$, with
65    /// $\operatorname{bits}(0) = 0$. The larger of the two counts alone is available as
66    /// [`max_significant_bits`](GaussianInteger::max_significant_bits).
67    ///
68    /// # Worst-case complexity
69    /// Constant time and additional memory.
70    ///
71    /// # Examples
72    /// ```
73    /// use malachite_base::num::basic::traits::Zero;
74    /// use malachite_base::num::logic::traits::SignificantBits;
75    /// use malachite_nz::gaussian_integer::GaussianInteger;
76    /// use std::str::FromStr;
77    ///
78    /// assert_eq!(GaussianInteger::ZERO.significant_bits(), 0);
79    /// assert_eq!(GaussianInteger::from(100).significant_bits(), 7);
80    /// assert_eq!(
81    ///     GaussianInteger::from_str("3+4i")
82    ///         .unwrap()
83    ///         .significant_bits(),
84    ///     5
85    /// );
86    /// assert_eq!(
87    ///     GaussianInteger::from_str("1000000000000+i")
88    ///         .unwrap()
89    ///         .significant_bits(),
90    ///     41
91    /// );
92    /// ```
93    #[inline]
94    fn significant_bits(self) -> u64 {
95        self.real.significant_bits() + self.imaginary.significant_bits()
96    }
97}