malachite_float/float/arithmetic/canonicalize_unit.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::Float;
10use malachite_base::num::arithmetic::traits::{
11 AbsAssign, CanonicalizeUnit, CanonicalizeUnitAssign, IsUnit,
12};
13
14impl CanonicalizeUnit for Float {
15 type Output = Self;
16
17 /// Brings a [`Float`] into canonical unit form, taking it by value.
18 ///
19 /// A finite nonzero [`Float`] is a unit, since it has a multiplicative inverse, so its
20 /// canonical form is 1, with the same precision. The other values are not units, and their
21 /// canonical form is their absolute value: both zeros become $0.0$, both infinities become
22 /// $\infty$, and NaN stays NaN.
23 ///
24 /// # Worst-case complexity
25 /// Constant time and additional memory.
26 ///
27 /// # Examples
28 /// ```
29 /// use malachite_base::num::arithmetic::traits::CanonicalizeUnit;
30 /// use malachite_base::num::basic::traits::{NaN, NegativeInfinity, NegativeZero};
31 /// use malachite_float::Float;
32 ///
33 /// assert_eq!(Float::from(-1.5).canonicalize_unit().to_string(), "1.0");
34 /// assert_eq!(Float::NEGATIVE_ZERO.canonicalize_unit().to_string(), "0.0");
35 /// assert_eq!(
36 /// Float::NEGATIVE_INFINITY.canonicalize_unit().to_string(),
37 /// "Infinity"
38 /// );
39 /// assert_eq!(Float::NAN.canonicalize_unit().to_string(), "NaN");
40 /// ```
41 #[inline]
42 fn canonicalize_unit(mut self) -> Self {
43 self.canonicalize_unit_assign();
44 self
45 }
46}
47
48impl CanonicalizeUnit for &Float {
49 type Output = Float;
50
51 /// Brings a [`Float`] into canonical unit form, taking it by reference.
52 ///
53 /// A finite nonzero [`Float`] is a unit, since it has a multiplicative inverse, so its
54 /// canonical form is 1, with the same precision. The other values are not units, and their
55 /// canonical form is their absolute value: both zeros become $0.0$, both infinities become
56 /// $\infty$, and NaN stays NaN.
57 ///
58 /// # Worst-case complexity
59 /// Constant time and additional memory.
60 ///
61 /// # Examples
62 /// ```
63 /// use malachite_base::num::arithmetic::traits::CanonicalizeUnit;
64 /// use malachite_base::num::basic::traits::{NaN, NegativeInfinity, NegativeZero};
65 /// use malachite_float::Float;
66 ///
67 /// assert_eq!((&Float::from(-1.5)).canonicalize_unit().to_string(), "1.0");
68 /// assert_eq!(
69 /// (&Float::NEGATIVE_ZERO).canonicalize_unit().to_string(),
70 /// "0.0"
71 /// );
72 /// assert_eq!(
73 /// (&Float::NEGATIVE_INFINITY).canonicalize_unit().to_string(),
74 /// "Infinity"
75 /// );
76 /// assert_eq!((&Float::NAN).canonicalize_unit().to_string(), "NaN");
77 /// ```
78 #[inline]
79 fn canonicalize_unit(self) -> Float {
80 if self.is_unit() {
81 Float::one_prec(self.get_prec().unwrap())
82 } else {
83 self.clone().canonicalize_unit()
84 }
85 }
86}
87
88impl CanonicalizeUnitAssign for Float {
89 /// Replaces a [`Float`] with its canonical unit form.
90 ///
91 /// A finite nonzero [`Float`] is a unit, since it has a multiplicative inverse, so its
92 /// canonical form is 1, with the same precision. The other values are not units, and their
93 /// canonical form is their absolute value: both zeros become $0.0$, both infinities become
94 /// $\infty$, and NaN stays NaN.
95 ///
96 /// # Worst-case complexity
97 /// Constant time and additional memory.
98 ///
99 /// # Examples
100 /// ```
101 /// use malachite_base::num::arithmetic::traits::CanonicalizeUnitAssign;
102 /// use malachite_float::Float;
103 ///
104 /// let mut x = Float::from(-1.5);
105 /// x.canonicalize_unit_assign();
106 /// assert_eq!(x.to_string(), "1.0");
107 /// ```
108 #[inline]
109 fn canonicalize_unit_assign(&mut self) {
110 if self.is_unit() {
111 *self = Self::one_prec(self.get_prec().unwrap());
112 } else {
113 self.abs_assign();
114 }
115 }
116}