Skip to main content

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}