dashu_float/
sign.rs

1use crate::{
2    fbig::FBig,
3    repr::{Context, Repr, Word},
4    round::Round,
5};
6use core::ops::{Mul, MulAssign, Neg};
7use dashu_base::{Abs, Sign, Signed};
8use dashu_int::IBig;
9
10impl<R: Round, const B: Word> FBig<R, B> {
11    /// Get the sign of the number. Zero value has a positive sign.
12    ///
13    /// # Examples
14    ///
15    /// ```
16    /// # use core::str::FromStr;
17    /// # use dashu_base::{ParseError, Sign};
18    /// # use dashu_float::DBig;
19    /// assert_eq!(DBig::ZERO.sign(), Sign::Positive);
20    /// assert_eq!(DBig::from_str("-1.234")?.sign(), Sign::Negative);
21    /// # Ok::<(), ParseError>(())
22    /// ```
23    #[inline]
24    pub const fn sign(&self) -> Sign {
25        self.repr.sign()
26    }
27
28    /// A number representing the sign of `self`.
29    ///
30    /// * [FBig::ONE] if the number is positive (including `inf`)
31    /// * [FBig::ZERO] if the number is zero
32    /// * [FBig::NEG_ONE] if the number is negative (including `-inf`)
33    ///
34    /// # Examples
35    /// ```
36    /// # use core::str::FromStr;
37    /// # use dashu_base::ParseError;
38    /// # use dashu_float::DBig;
39    /// assert_eq!(DBig::from_str("2.01")?.signum(), DBig::ONE);
40    /// assert_eq!(DBig::from_str("-1.234")?.signum(), DBig::NEG_ONE);
41    /// # Ok::<(), ParseError>(())
42    /// ```
43    pub const fn signum(&self) -> Self {
44        let significand = if self.repr.significand.is_zero() && self.repr.exponent != 0 {
45            if self.repr.exponent > 0 {
46                IBig::ONE
47            } else {
48                IBig::NEG_ONE
49            }
50        } else {
51            self.repr.significand.signum()
52        };
53        let repr = Repr {
54            significand,
55            exponent: 0,
56        };
57        Self::new(repr, Context::new(1))
58    }
59}
60
61impl<const B: Word> Neg for Repr<B> {
62    type Output = Self;
63    #[inline]
64    fn neg(mut self) -> Self::Output {
65        self.significand = -self.significand;
66        self
67    }
68}
69
70impl<R: Round, const B: Word> Neg for FBig<R, B> {
71    type Output = Self;
72    #[inline]
73    fn neg(mut self) -> Self::Output {
74        self.repr.significand = -self.repr.significand;
75        self
76    }
77}
78
79impl<R: Round, const B: Word> Neg for &FBig<R, B> {
80    type Output = FBig<R, B>;
81    #[inline]
82    fn neg(self) -> Self::Output {
83        self.clone().neg()
84    }
85}
86
87impl<R: Round, const B: Word> Abs for FBig<R, B> {
88    type Output = Self;
89    fn abs(mut self) -> Self::Output {
90        self.repr.significand = self.repr.significand.abs();
91        self
92    }
93}
94
95impl<R: Round, const B: Word> Mul<FBig<R, B>> for Sign {
96    type Output = FBig<R, B>;
97    #[inline]
98    fn mul(self, mut rhs: FBig<R, B>) -> Self::Output {
99        rhs.repr.significand *= self;
100        rhs
101    }
102}
103
104impl<R: Round, const B: Word> Mul<Sign> for FBig<R, B> {
105    type Output = FBig<R, B>;
106    #[inline]
107    fn mul(mut self, rhs: Sign) -> Self::Output {
108        self.repr.significand *= rhs;
109        self
110    }
111}
112
113impl<R: Round, const B: Word> MulAssign<Sign> for FBig<R, B> {
114    #[inline]
115    fn mul_assign(&mut self, rhs: Sign) {
116        self.repr.significand *= rhs;
117    }
118}
119
120impl<R: Round, const B: Word> Signed for FBig<R, B> {
121    #[inline]
122    fn sign(&self) -> Sign {
123        self.repr.sign()
124    }
125}