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}