Skip to main content

feldera_fxp/
fixed.rs

1use std::{
2    cmp::Ordering,
3    fmt::{Debug, Display},
4    ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign},
5    str::FromStr,
6};
7
8use num_traits::{CheckedAdd, CheckedDiv, CheckedMul, CheckedSub, One, Zero, cast};
9
10use crate::{
11    Halfway, OutOfRange, ParseDecimalError, checked_pow10, debug_decimal, display_decimal,
12    div_ceil, div_floor, i128_mul_pow10_round_even, parse_decimal, pow10, round_inner, u256::I256,
13};
14
15/// Decimal real number with fixed precision and scale.
16///
17/// `Fixed<P, S>`, where `P` in `1..=38` is the "precision" and `S` in `0..=P`
18/// is the "scale", represents a signed decimal number in which `S - P` digits
19/// precede the decimal point and `S` digits follow it.  The table below shows
20/// the maximum values for a few combinations of `P` and `S`.  For each type,
21/// the minimum value is the negation of the maximum:
22///
23/// |          Type |                                              Maximum Value |
24/// |:--------------|-----------------------------------------------------------:|
25/// | `Fixed<5,5>`  | `                                                 0.99999` |
26/// | `Fixed<5,4>`  | `                                                 9.9999 ` |
27/// | `Fixed<5,3>`  | `                                                99.999  ` |
28/// | `Fixed<5,2>`  | `                                               999.99   ` |
29/// | `Fixed<5,1>`  | `                                             9,999.9    ` |
30/// | `Fixed<5,0>`  | `                                            99,999      ` |
31/// | `Fixed<38,0>` | `99,999,999,999,999,999,999,999,999,999,999,999,999      ` |
32/// | `Fixed<38,5>` | `       999,999,999,999,999,999,999,999,999,999,999.99999` |
33///
34/// # Implementation
35///
36/// `Fixed<P, S>` internally contains a single `i128` that represents a value
37/// `x` as `x * 10**P`.  This limits `S` to 38 because `10**38 ≤ 2**127 - 1 <
38/// 10**39`.  A single `i64` would be sufficient for `S ≤ 18`, and a single
39/// `i32` for `S ≤ 9`, but the implementation does not optimize for those cases.
40#[derive(Copy, Clone, Default, Eq, Ord, Hash)]
41#[cfg_attr(feature = "size_of", derive(size_of::SizeOf))]
42pub struct Fixed<const P: usize, const S: usize>(pub(super) i128);
43
44impl<const P0: usize, const S0: usize, const P1: usize, const S1: usize> PartialEq<Fixed<P1, S1>>
45    for Fixed<P0, S0>
46{
47    fn eq(&self, other: &Fixed<P1, S1>) -> bool {
48        match S0.cmp(&S1) {
49            Ordering::Less => I256::from_product(self.0, pow10(S1 - S0)) == I256::from(other.0),
50            Ordering::Equal => self.0 == other.0,
51            Ordering::Greater => I256::from(self.0) == I256::from_product(other.0, pow10(S0 - S1)),
52        }
53    }
54}
55
56macro_rules! partial_eq_int {
57    ($type_name:ty) => {
58        impl<const P0: usize, const S0: usize> PartialEq<$type_name> for Fixed<P0, S0> {
59            fn eq(&self, other: &$type_name) -> bool {
60                self.0 % Self::scale() == 0 && self.0 / Self::scale() == *other as i128
61            }
62        }
63    };
64}
65partial_eq_int!(i8);
66partial_eq_int!(i16);
67partial_eq_int!(i32);
68partial_eq_int!(i64);
69partial_eq_int!(i128);
70partial_eq_int!(isize);
71partial_eq_int!(u8);
72partial_eq_int!(u16);
73partial_eq_int!(u32);
74partial_eq_int!(u64);
75
76impl<const P0: usize, const S0: usize> PartialEq<u128> for Fixed<P0, S0> {
77    fn eq(&self, other: &u128) -> bool {
78        self.0 >= 0
79            && self.0 % Self::scale() == 0
80            && (self.0 / Self::scale()).cast_unsigned() == *other
81    }
82}
83
84impl<const P0: usize, const S0: usize> PartialEq<usize> for Fixed<P0, S0> {
85    fn eq(&self, other: &usize) -> bool {
86        self.0 >= 0
87            && self.0 % Self::scale() == 0
88            && (self.0 / Self::scale()).cast_unsigned() == *other as u128
89    }
90}
91
92impl<const P0: usize, const S0: usize, const P1: usize, const S1: usize> PartialOrd<Fixed<P1, S1>>
93    for Fixed<P0, S0>
94{
95    fn partial_cmp(&self, other: &Fixed<P1, S1>) -> Option<Ordering> {
96        match S0.cmp(&S1) {
97            Ordering::Less => {
98                I256::from_product(self.0, pow10(S1 - S0)).partial_cmp(&I256::from(other.0))
99            }
100            Ordering::Equal => self.0.partial_cmp(&other.0),
101            Ordering::Greater => {
102                I256::from(self.0).partial_cmp(&I256::from_product(other.0, pow10(S0 - S1)))
103            }
104        }
105    }
106}
107
108impl<const P: usize, const S: usize> Fixed<P, S> {
109    /// Largest value for this type, e.g. 999.99 for `Fixed<5,2>`.
110    pub const MAX: Self = Self(pow10(P) - 1);
111
112    /// Smallest value for this type, e.g. -999.99 for `Fixed<5,2>`.
113    ///
114    /// `MIN` is always `-MAX`.
115    pub const MIN: Self = Self(-Self::MAX.0);
116
117    /// Zero in this type.
118    pub const ZERO: Self = Self(0);
119
120    /// 1 in this type.
121    ///
122    /// # Panic
123    ///
124    /// If `S == P`, this is undefined because 1 is not a value in this type,
125    /// and referring to it yields a compile-time error.
126    pub const ONE: Self = {
127        if S < P {
128            Self(pow10(S))
129        } else {
130            panic!("all values of Fixed::<S,P>::one() for S >= P have magnitude less than one");
131        }
132    };
133
134    /// Returns the mantissa of this fixed-point decimal number.
135    ///
136    /// The mantissa is the unscaled integer representation of the decimal value.
137    /// For a decimal number `d` with a given scale `s`, the mantissa `m` satisfies:
138    /// `d = m × 10^(-s)`, or equivalently, `m = d × 10^s`.
139    pub fn mantissa(&self) -> i128 {
140        self.0
141    }
142
143    /// Returns `value` in this type.
144    ///
145    /// # Panic
146    ///
147    /// Panics if this type cannot hold every `i64` value.
148    pub const fn for_i64(value: i64) -> Self {
149        assert!(P.saturating_sub(S) >= 19);
150        Self(value as i128 * Self::scale())
151    }
152
153    /// Returns `value` in this type.
154    ///
155    /// # Panic
156    ///
157    /// Panics if this type cannot hold every `u64` value.
158    pub const fn for_u64(value: u64) -> Self {
159        assert!(P.saturating_sub(S) >= 19);
160        Self(value as i128 * Self::scale())
161    }
162
163    /// Returns `value` in this type.
164    ///
165    /// # Panic
166    ///
167    /// Panics if this type cannot hold every `i32` value.
168    pub const fn for_i32(value: i32) -> Self {
169        assert!(P.saturating_sub(S) >= 10);
170        Self(value as i128 * Self::scale())
171    }
172
173    /// Returns `value` in this type.
174    ///
175    /// # Panic
176    ///
177    /// Panics if this type cannot hold every `u32` value.
178    pub const fn for_u32(value: u32) -> Self {
179        assert!(P.saturating_sub(S) >= 10);
180        Self(value as i128 * Self::scale())
181    }
182
183    /// Returns `value` in this type.
184    ///
185    /// # Panic
186    ///
187    /// Panics if this type cannot hold every `i16` value.
188    pub const fn for_i16(value: i16) -> Self {
189        assert!(P.saturating_sub(S) >= 5);
190        Self(value as i128 * Self::scale())
191    }
192
193    /// Returns `value` in this type.
194    ///
195    /// # Panic
196    ///
197    /// Panics if this type cannot hold every `u16` value.
198    pub const fn for_u16(value: u16) -> Self {
199        assert!(P.saturating_sub(S) >= 5);
200        Self(value as i128 * Self::scale())
201    }
202
203    /// Returns `value` in this type.
204    ///
205    /// # Panic
206    ///
207    /// Panics if this type cannot hold every `i8` value.
208    pub const fn for_i8(value: i8) -> Self {
209        assert!(P.saturating_sub(S) >= 3);
210        Self(value as i128 * Self::scale())
211    }
212
213    /// Returns `value` in this type.
214    ///
215    /// # Panic
216    ///
217    /// Panics if this type cannot hold every `u8` value.
218    pub const fn for_u8(value: u8) -> Self {
219        assert!(P.saturating_sub(S) >= 3);
220        Self(value as i128 * Self::scale())
221    }
222
223    /// Returns `value` in this type.
224    ///
225    /// # Panic
226    ///
227    /// Panics if this type cannot hold every `isize` value.
228    pub const fn for_isize(value: isize) -> Self {
229        match isize::BITS {
230            64 => Self::for_i64(value as i64),
231            32 => Self::for_i32(value as i32),
232            16 => Self::for_i16(value as i16),
233            _ => panic!(),
234        }
235    }
236
237    /// Returns `value` in this type.
238    ///
239    /// # Panic
240    ///
241    /// Panics if this type cannot hold every `usize` value.
242    pub const fn for_usize(value: usize) -> Self {
243        match usize::BITS {
244            64 => Self::for_u64(value as u64),
245            32 => Self::for_u32(value as u32),
246            16 => Self::for_u16(value as u16),
247            _ => panic!(),
248        }
249    }
250
251    /// Returns the value that represents `value * 10**-scale`, rounding
252    /// toward zero if necessary, or `None` if the rounded value is out of range
253    /// for this type.
254    ///
255    /// # Examples
256    ///
257    /// ```
258    /// # use feldera_fxp::Fixed;
259    ///
260    /// assert_eq!(Fixed::<11, 1>::new(435, 0).unwrap().to_string(), "435");
261    /// assert_eq!(Fixed::<11, 1>::new(435, 1).unwrap().to_string(), "43.5");
262    /// assert_eq!(Fixed::<11, 1>::new(435, 2).unwrap().to_string(), "4.3");
263    /// assert_eq!(Fixed::<11, 1>::new(435, 3).unwrap().to_string(), "0.4");
264    /// ```
265    pub fn new(value: i128, scale: i32) -> Option<Self> {
266        Self::try_new_with_exponent(value, (S as i32).saturating_sub(scale))
267    }
268
269    /// Returns the value that represents `value * 10**-scale`, rounding to
270    /// nearest if necessary, with ties rounded to even, or `None` if the
271    /// rounded value is out of range for this type.
272    ///
273    /// # Examples
274    ///
275    /// ```
276    /// # use feldera_fxp::Fixed;
277    ///
278    /// assert_eq!(Fixed::<11, 1>::new_round_even(435, 0).unwrap().to_string(), "435");
279    /// assert_eq!(Fixed::<11, 1>::new_round_even(435, 1).unwrap().to_string(), "43.5");
280    /// assert_eq!(Fixed::<11, 1>::new_round_even(435, 2).unwrap().to_string(), "4.4");
281    /// assert_eq!(Fixed::<11, 1>::new_round_even(435, 3).unwrap().to_string(), "0.4");
282    /// ```
283    pub fn new_round_even(value: i128, scale: i32) -> Option<Self> {
284        Self::try_new_with_exponent_round_even(value, (S as i32).saturating_sub(scale))
285    }
286
287    /// Returns `Self(value)`, if `value` is in the correct range for this type.
288    fn try_new(value: i128) -> Option<Self> {
289        const { Self::check_constraints() };
290        (Self::MIN.0..=Self::MAX.0)
291            .contains(&value)
292            .then_some(Self(value))
293    }
294
295    /// Returns the internal representation of this Fixed value
296    /// This is an unstable API, use at your own risk!
297    pub fn internal_representation(self) -> i128 {
298        self.0
299    }
300
301    /// Returns `Self(value * 10**exponent)`, rounding to even if `exponent` is
302    /// negative, if the computed value is in the correct range for the type.
303    pub(super) fn try_new_with_exponent_round_even(value: i128, exponent: i32) -> Option<Self> {
304        i128_mul_pow10_round_even(value, exponent).and_then(Self::try_new)
305    }
306
307    /// Returns `Self(value * 10**exponent)`, rounding toward zero, if the
308    /// computed value is in the correct range for the type.
309    pub(super) fn try_new_with_exponent(value: i128, exponent: i32) -> Option<Self> {
310        // Non-generic inner function to reduce monomorphization cost.
311        fn inner(value: i128, exponent: i32) -> Option<i128> {
312            Some(match exponent.cmp(&0) {
313                Ordering::Less => {
314                    // Divide by a negative exponent.
315                    if let Some(divisor) = checked_pow10(exponent.unsigned_abs()) {
316                        value / divisor
317                    } else {
318                        // `10**-exponent` is greater than `i128::MAX`.  The result
319                        // must be zero.
320                        0
321                    }
322                }
323                Ordering::Equal => value,
324                Ordering::Greater => {
325                    // Multiply by a positive exponent.
326                    value.checked_mul(checked_pow10(exponent.cast_unsigned())?)?
327                }
328            })
329        }
330        inner(value, exponent).and_then(Self::try_new)
331    }
332
333    /// Validates the constraints on `S` and `P`.
334    const fn check_constraints() {
335        assert!(P >= 1 && P <= 38, "Fixed<S,P> must have 1 <= S <= 38");
336        assert!(S <= P, "Fixed<S,P> must have S <= P");
337    }
338
339    /// Returns `pow10(S)`.
340    const fn scale() -> i128 {
341        Self::check_constraints();
342        pow10(S)
343    }
344
345    /// Integer division, as defined for `divide-integer` in [General Decimal
346    /// Arithmetic].  Returns `None` if `other` is zero or the result is greater
347    /// than `i128::MAX`.
348    ///
349    /// [General Decimal Arithmetic]: https://speleotrove.com/decimal/decarith.pdf
350    pub const fn checked_div_integer(self, other: Self) -> Option<i128> {
351        self.0.checked_div(other.0)
352    }
353
354    /// Integer division like [checked_div_integer](Self::checked_div_integer),
355    /// but panic on error.
356    ///
357    /// # Panic
358    ///
359    /// Panics if `other` is zero or the result is greater than `i128::MAX`.
360    pub const fn strict_div_integer(self, other: Self) -> i128 {
361        self.checked_div_integer(other).unwrap()
362    }
363
364    /// Remainder, as defined for `remainder` in [General Decimal Arithmetic].
365    /// Returns `None` if `other` is zero.
366    ///
367    /// [General Decimal Arithmetic]: https://speleotrove.com/decimal/decarith.pdf
368    pub fn checked_rem<const P0: usize, const S0: usize, const P1: usize, const S1: usize>(
369        self,
370        other: Fixed<P0, S0>,
371    ) -> Option<Fixed<P1, S1>> {
372        let neg = self.is_negative();
373        let left = self.abs();
374        let right = other.abs();
375        let div: Self = left.checked_div_generic(right)?;
376        let trunc: Self = div.trunc();
377        let mul: Self = right.checked_mul_generic(trunc)?;
378        let rem: Fixed<P1, S1> = left.checked_sub_generic(mul)?;
379        Some(if neg { rem.neg() } else { rem })
380    }
381
382    /// Returns the absolute value.  This is an exact calculation that cannot
383    /// overflow.
384    pub const fn abs(self) -> Self {
385        Self(self.0.abs())
386    }
387
388    /// Returns true if this value is negative, false if it is zero or positive.
389    pub const fn is_negative(self) -> bool {
390        self.0.is_negative()
391    }
392
393    /// Returns the square root of this value, rounded down, or `None` if this
394    /// value is negative.
395    ///
396    /// It probably makes more sense to convert to `f64` and take the
397    /// floating-point square root.
398    pub fn checked_sqrt(self) -> Option<Self> {
399        Some(Self(
400            I256::from_product(self.0, Self::scale()).checked_isqrt()?,
401        ))
402    }
403
404    /// Returns the square root of this value, rounded down.
405    ///
406    /// It probably makes more sense to convert to `f64` and take the
407    /// floating-point square root.
408    ///
409    /// # Panic
410    ///
411    /// Panics if this value is negative.
412    pub fn sqrt(self) -> Self {
413        self.checked_sqrt().unwrap()
414    }
415
416    /// Returns this value rounded to `n` digits after the decimal point, or
417    /// `None` if rounding caused overflow, `n` may be negative.
418    ///
419    /// If the value is halfway between two integers, rounds away from zero.
420    pub fn checked_round(&self, n: i32) -> Option<Self> {
421        round_inner(self.0, S as i32, n, Halfway::AwayFromZero).and_then(Self::try_new)
422    }
423
424    /// Rounds to `n` digits after the decimal point, like [checked_round].
425    /// If the value is halfway between two integers, rounds away from zero.
426    ///
427    /// # Panic
428    ///
429    /// Panics if rounding causes overflow.
430    ///
431    /// [checked_round]: Self::checked_round
432    pub fn round(&self, n: i32) -> Self {
433        self.checked_round(n)
434            .unwrap_or_else(|| panic!("Could not round value {} to {} digits", self, n))
435    }
436
437    /// Returns this value rounded to `n` digits after the decimal point, or
438    /// `None` if rounding caused overflow, `n` may be negative.  If the value
439    /// is halfway between two integers, rounds toward an even least significant
440    /// digit.
441    pub fn checked_round_ties_even(&self, n: i32) -> Option<Self> {
442        round_inner(self.0, S as i32, n, Halfway::Even).and_then(Self::try_new)
443    }
444
445    /// Rounds to `n` digits after the decimal point, like
446    /// [checked_round_ties_even].  If the value is halfway between two
447    /// integers, rounds toward an even least significant digit.
448    ///
449    /// # Panic
450    ///
451    /// Panics if rounding causes overflow.
452    ///
453    /// [checked_round_ties_even]: Self::checked_round_ties_even
454    pub fn round_ties_even(&self, n: i32) -> Self {
455        self.checked_round_ties_even(n).unwrap()
456    }
457
458    /// Returns this value rounded down to the nearest integer, or `None` if
459    /// rounding caused overflow.
460    pub fn checked_floor(&self) -> Option<Self> {
461        if S > 0 {
462            Self::try_new(div_floor(self.0, Self::scale()) * Self::scale())
463        } else {
464            Some(*self)
465        }
466    }
467
468    /// Rounds down to the nearest integer, like [checked_floor].
469    ///
470    /// # Panic
471    ///
472    /// Panics if rounding causes overflow.
473    ///
474    /// [checked_floor]: Self::checked_floor
475    pub fn floor(&self) -> Self {
476        self.checked_floor().unwrap()
477    }
478
479    /// Returns this value rounded down to the nearest integer, with type Fixed<P, 0>
480    pub fn int_floor(&self) -> Fixed<P, 0> {
481        if S > 0 {
482            Fixed::<P, 0>::new(div_floor(self.0, Self::scale()), 0i32).unwrap()
483        } else {
484            Fixed::<P, 0>::new(self.0, S as i32).unwrap()
485        }
486    }
487
488    /// Returns the integer part of this value, truncating non-integers toward
489    /// zero.  This is an exact calculation that cannot overflow.
490    ///
491    /// `trunc()` is equivalent to `trunc_digits(0)`, but it might be more
492    /// efficient due to constant folding.
493    pub fn trunc(&self) -> Self {
494        Self(self.0 / Self::scale() * Self::scale())
495    }
496
497    /// Returns this value, truncated toward zero at `digits` after the decimal
498    /// point. This is an exact calculation that cannot overflow.
499    pub fn trunc_digits(&self, digits: i32) -> Self {
500        let exponent = (S as i32).saturating_sub(digits);
501        if exponent <= 0 {
502            *self
503        } else if let Some(divisor) = checked_pow10(exponent.cast_unsigned()) {
504            Self(self.0 / divisor * divisor)
505        } else {
506            Self::ZERO
507        }
508    }
509
510    /// Returns this value rounded up to the nearest integer, or `None` if
511    /// rounding caused overflow.
512    pub fn checked_ceil(&self) -> Option<Self> {
513        if S > 0 {
514            Self::try_new(div_ceil(self.0, Self::scale()) * Self::scale())
515        } else {
516            Some(*self)
517        }
518    }
519
520    /// Rounds up to the nearest integer, like [checked_ceil].
521    ///
522    /// # Panic
523    ///
524    /// Panics if rounding causes overflow.
525    ///
526    /// [checked_ceil]: Self::checked_ceil
527    pub fn ceil(&self) -> Self {
528        self.checked_ceil().unwrap()
529    }
530
531    /// Returns this value rounded up to the nearest integer, or `None` if
532    /// rounding caused overflow.
533    pub fn int_ceil(&self) -> Fixed<P, 0> {
534        if S > 0 {
535            Fixed::<P, 0>::new(div_ceil(self.0, Self::scale()), 0i32).unwrap()
536        } else {
537            Fixed::<P, 0>::new(self.0, S as i32).unwrap()
538        }
539    }
540
541    /// Returns -1 if this value is less than zero, 0 if this value is zero, and
542    /// 1 if this value is greater than zero, as `Fixed<1,0>`.
543    pub fn sign(&self) -> Fixed<1, 0> {
544        self.checked_sign_generic().unwrap()
545    }
546
547    /// Returns the reciprocal (inverse) of this value, `1/x`, or `None` if `x`
548    /// is zero or `1/x` is out of range.
549    pub fn checked_recip(&self) -> Option<Self> {
550        if S < P {
551            Self(Self::scale()).checked_div(self)
552        } else {
553            // `1` is out of range for this type, therefore `abs(self) < 1`,
554            // therefore `abs(1/self) > 1`, therefore the result is out of
555            // range.
556            None
557        }
558    }
559
560    /// Returns the reciprocal (inverse) of this value, `1/x`.  This works even
561    /// if `1` is out of range for this type, as long as `1/x` is in range.
562    ///
563    /// # Panic
564    ///
565    /// Panics if `x` is zero or `1/x` is out of range.
566    pub fn recip(&self) -> Self {
567        self.checked_recip().unwrap()
568    }
569
570    /// Returns this value raised to `exp` power, rounding toward zero, or
571    /// `None` if the result is out of range or if this value is 0 and `exp` is
572    /// nonpositive.
573    ///
574    /// # Accuracy
575    ///
576    /// For `exp > 0`, this computes intermediate results with more than `S`
577    /// digits of precision, if possible, to allow to better accuracy in the
578    /// result.  For `exp < 0`, this isn't implemented yet.
579    pub fn checked_powi(&self, exp: i32) -> Option<Self> {
580        if self.is_zero() {
581            (exp > 0).then_some(Self::ZERO)
582        } else if exp == 0 {
583            if S < P {
584                Some(Self::ONE)
585            } else {
586                // 1 is not representable.
587                None
588            }
589        } else if exp > 0 {
590            let mut exp = exp.unsigned_abs();
591            let mut base = self.0;
592            let mut base_scale = S as i32;
593            let mut acc = None;
594            loop {
595                if (exp & 1) == 1 {
596                    acc = if let Some((acc, acc_scale)) = acc {
597                        let (acc, shift) = I256::from_product(acc, base).reduce_to_i128();
598                        Some((acc, (acc_scale + base_scale) - shift as i32))
599                    } else {
600                        Some((base, base_scale))
601                    };
602                }
603                exp /= 2;
604                if exp == 0 {
605                    let (acc, acc_scale) = acc.unwrap();
606                    return Self::try_new_with_exponent(acc, S as i32 - acc_scale);
607                }
608
609                let (next_base, shift) = I256::from_product(base, base).reduce_to_i128();
610                base = next_base;
611                base_scale = base_scale * 2 - shift as i32;
612            }
613        } else {
614            let mut exp = exp.unsigned_abs();
615            let mut base = *self;
616            let mut acc: Option<Fixed<P, S>> = None;
617            loop {
618                if (exp & 1) == 1 {
619                    acc = Some(if let Some(acc) = acc {
620                        acc.checked_div(&base)
621                    } else {
622                        base.checked_recip()
623                    }?)
624                }
625                exp /= 2;
626                if exp == 0 {
627                    return acc;
628                }
629                base *= base;
630            }
631        }
632    }
633
634    /// Returns this value raised to `exp` power, rounding toward zero.
635    ///
636    /// For `exp > 0`, this computes intermediate results with more than `S`
637    /// digits of precision, if possible, to allow to better accuracy in the
638    /// result.  For `exp < 0`, this isn't implemented yet.
639    ///
640    /// # Panics
641    ///
642    /// Panics if the result is out of range or if this value is 0 and `exp` is
643    /// nonpositive.
644    pub fn powi(&self, exp: i32) -> Self {
645        self.checked_powi(exp).unwrap()
646    }
647
648    /// Returns the least number greater than `self`, or `None` if this is
649    /// `Self::MAX`.
650    pub fn next_up(&self) -> Option<Self> {
651        if *self < Self::MAX {
652            Some(Self(self.0 + 1))
653        } else {
654            None
655        }
656    }
657
658    /// Returns the greatest number less than `self`, or `None` if this is
659    /// `Self::MAX`.
660    pub fn next_down(&self) -> Option<Self> {
661        if *self > Self::MIN {
662            Some(Self(self.0 - 1))
663        } else {
664            None
665        }
666    }
667}
668
669impl<const P0: usize, const S0: usize> Fixed<P0, S0> {
670    /// Returns this value converted into another type `Fixed<P1, S1>`, or
671    /// `None` if this value is outside the range of the target type.  If the
672    /// conversion is successful, then the result is exactly the same as the
673    /// original value if `S1 >= S0`, and rounded down otherwise.
674    ///
675    /// This should be implemented as `TryFrom` but that [conflicts with the
676    /// standard library
677    /// implementation](https://users.rust-lang.org/t/conflicting-implementations-of-trait-from/92994).
678    pub fn convert<const P1: usize, const S1: usize>(&self) -> Option<Fixed<P1, S1>> {
679        Fixed::try_new_with_exponent(self.0, S1 as i32 - S0 as i32)
680    }
681
682    /// Returns this value converted into another type `Fixed<P1, S1>`, or
683    /// `None` if this value is outside the range of the target type.  If the
684    /// conversion is successful, then the result is exactly the same as the
685    /// original value if `S1 >= S0`, and rounded to even otherwise.
686    pub fn convert_round_even<const P1: usize, const S1: usize>(&self) -> Option<Fixed<P1, S1>> {
687        Fixed::try_new_with_exponent_round_even(self.0, S1 as i32 - S0 as i32)
688    }
689
690    /// Returns -1 if this value is less than zero, 0 if this value is zero, and
691    /// 1 if this value is greater than zero, in an arbitrary `Fixed` type.
692    /// Returns `None` on overflow (if this value is nonzero and `S1 >= P1`).
693    pub fn checked_sign_generic<const P1: usize, const S1: usize>(&self) -> Option<Fixed<P1, S1>> {
694        let one = Fixed::<P1, S1>::scale();
695        match self.0.cmp(&0) {
696            Ordering::Less if S1 < P1 => Some(Fixed(-one)),
697            Ordering::Equal => Some(Fixed::ZERO),
698            Ordering::Greater if S1 < P1 => Some(Fixed(one)),
699            _ => None,
700        }
701    }
702
703    /// Calculates `self + other`, for operands with scale and precision `(S0,P0)` and
704    /// `(S1,P1)`, respectively, producing a result with scale and precision
705    /// `(S2,P2)`.  The result is calculated exactly if possible and otherwise
706    /// rounded toward zero.  Returns `None` if the result is not representable
707    /// in the result type.
708    pub fn checked_add_generic<
709        const P1: usize,
710        const S1: usize,
711        const P2: usize,
712        const S2: usize,
713    >(
714        self,
715        other: Fixed<P1, S1>,
716    ) -> Option<Fixed<P2, S2>> {
717        match S0.cmp(&S1) {
718            Ordering::Less => {
719                let factor = pow10(S1 - S0);
720                if let Some(shifted) = self.0.checked_mul(factor)
721                    && let Some(sum) = other.0.checked_add(shifted)
722                {
723                    // This is the common case, where we can shift `self` left
724                    // to match `other` and add `other` without intermediate
725                    // overflow.
726                    Fixed::try_new_with_exponent(sum, S2 as i32 - S1 as i32)
727                } else {
728                    // If the result type has more digits to the left of the
729                    // decimal point than `other`, then we still might be able
730                    // to compute a correct answer without ultimate overflow.
731                    let result = (I256::from_product(self.0, factor) + I256::from(other.0))
732                        .narrowing_div(pow10(S1.saturating_sub(S2)))?;
733                    Fixed::try_new_with_exponent(result, (S2.saturating_sub(S1)) as i32)
734                }
735            }
736            Ordering::Equal => {
737                if let Some(sum) = self.0.checked_add(other.0) {
738                    // This is the common case, where the result fits in `i128`.
739                    Fixed::try_new_with_exponent(sum, S2 as i32 - S0 as i32)
740                } else if S2 < S0 {
741                    // The ultimate result might fit in `i128` but we need
742                    // multiple-precision arithmetic.
743                    Fixed::try_new(
744                        (I256::from(self.0) + I256::from(other.0)).narrowing_div(pow10(S0 - S2))?,
745                    )
746                } else {
747                    // Definitely does not fit.
748                    None
749                }
750            }
751            Ordering::Greater => {
752                // Mirror of the `Less` case.
753                let factor = pow10(S0 - S1);
754                if let Some(shifted) = other.0.checked_mul(factor)
755                    && let Some(sum) = self.0.checked_add(shifted)
756                {
757                    Fixed::try_new_with_exponent(sum, S2 as i32 - S0 as i32)
758                } else {
759                    let result = (I256::from_product(other.0, factor) + I256::from(self.0))
760                        .narrowing_div(pow10(S0.saturating_sub(S2)))?;
761                    Fixed::try_new_with_exponent(result, S2.saturating_sub(S0) as i32)
762                }
763            }
764        }
765    }
766
767    /// Calculates `self - other`, for operands with scale and precision
768    /// `(S0,P0)` and `(S1,P1)`, respectively, producing a result with scale and
769    /// precision `(S2,P2)`.  The result is calculated exactly if possible and
770    /// otherwise rounded toward zero.  Returns `None` if the result is not
771    /// representable in the result type.
772    pub fn checked_sub_generic<
773        const P1: usize,
774        const S1: usize,
775        const P2: usize,
776        const S2: usize,
777    >(
778        self,
779        other: Fixed<P1, S1>,
780    ) -> Option<Fixed<P2, S2>> {
781        self.checked_add_generic(-other)
782    }
783
784    /// Calculates `self * other`, for operands with scale and precision
785    /// `(S0,P0)` and `(S1,P1)`, respectively, producing a result with scale and
786    /// precision `(S2,P2)`.  The result is calculated exactly if possible and
787    /// otherwise rounded toward zero.  Returns `None` if the result is not
788    /// representable in the result type.
789    pub fn checked_mul_generic<
790        const P1: usize,
791        const S1: usize,
792        const P2: usize,
793        const S2: usize,
794    >(
795        self,
796        other: Fixed<P1, S1>,
797    ) -> Option<Fixed<P2, S2>> {
798        Fixed::<P2, S2>::try_new_with_exponent(
799            I256::from_product(self.0, other.0)
800                .narrowing_div(pow10((S0 + S1).saturating_sub(S2)))?,
801            S2.saturating_sub(S0 + S1) as i32,
802        )
803    }
804
805    /// Calculate `self / other`, for operands with scale and precision
806    /// `(S0,P0)` and `(S1,P1)`, respectively, producing a result with scale and
807    /// precision `(S2,P2)`.  The result is calculated exactly if possible and
808    /// otherwise rounded toward zero.  Returns `None` if the result is not
809    /// representable in the result type, or if `other` is zero.
810    pub fn checked_div_generic<
811        const P1: usize,
812        const S1: usize,
813        const P2: usize,
814        const S2: usize,
815    >(
816        self,
817        other: Fixed<P1, S1>,
818    ) -> Option<Fixed<P2, S2>> {
819        if other == 0 {
820            None
821        } else {
822            let shift_left = (S1 + S2).saturating_sub(S0);
823            if shift_left > 38 {
824                // A shift this big would exceed the range of I256, so we can't
825                // calculate it, but the ultimate result would also overflow, so
826                // we don't have to.
827                None
828            } else {
829                Fixed::try_new_with_exponent(
830                    I256::from_product(self.0, pow10(shift_left)).narrowing_div(other.0)?,
831                    -(S0.saturating_sub(S1 + S2) as i32),
832                )
833            }
834        }
835    }
836
837    /// Compute `self + other`, rounding toward zero, panicking if overflow
838    /// occurs.
839    pub fn strict_add_generic<
840        const P1: usize,
841        const S1: usize,
842        const P2: usize,
843        const S2: usize,
844    >(
845        self,
846        other: Fixed<P1, S1>,
847    ) -> Fixed<P2, S2> {
848        self.checked_add_generic(other).unwrap()
849    }
850
851    /// Compute `self - other`, rounding toward zero, panicking if overflow
852    /// occurs.
853    pub fn strict_sub_generic<
854        const P1: usize,
855        const S1: usize,
856        const P2: usize,
857        const S2: usize,
858    >(
859        self,
860        other: Fixed<P1, S1>,
861    ) -> Fixed<P2, S2> {
862        self.checked_sub_generic(other).unwrap()
863    }
864
865    /// Compute `self * other`, rounding toward zero, panicking if overflow
866    /// occurs.
867    pub fn strict_mul_generic<
868        const P1: usize,
869        const S1: usize,
870        const P2: usize,
871        const S2: usize,
872    >(
873        self,
874        other: Fixed<P1, S1>,
875    ) -> Fixed<P2, S2> {
876        self.checked_mul_generic(other).unwrap()
877    }
878
879    /// Compute `self / other`, rounding toward zero, panicking if overflow
880    /// occurs or if `other` is zero.
881    pub fn strict_div_generic<
882        const P1: usize,
883        const S1: usize,
884        const P2: usize,
885        const S2: usize,
886    >(
887        self,
888        other: Fixed<P1, S1>,
889    ) -> Fixed<P2, S2> {
890        self.checked_div_generic(other).unwrap()
891    }
892}
893
894impl<const P: usize, const S: usize> Zero for Fixed<P, S> {
895    fn zero() -> Self {
896        Self::ZERO
897    }
898
899    fn is_zero(&self) -> bool {
900        *self == Self::ZERO
901    }
902}
903
904impl<const P: usize, const S: usize> One for Fixed<P, S> {
905    /// This will panic at compile time if 1 isn't in the range of this type.
906    fn one() -> Self {
907        Self::ONE
908    }
909}
910
911impl<const P: usize, const S: usize> TryFrom<f64> for Fixed<P, S> {
912    type Error = OutOfRange;
913
914    /// Convert `value` to `Fixed`, rounding toward zero, reporting an error if
915    /// `value` is out of range.
916    fn try_from(value: f64) -> Result<Self, Self::Error> {
917        cast(value * Self::scale() as f64)
918            .and_then(Self::try_new)
919            .ok_or(OutOfRange)
920    }
921}
922
923impl<const P: usize, const S: usize> TryFrom<f32> for Fixed<P, S> {
924    type Error = OutOfRange;
925
926    /// Convert `value` to `Fixed`, rounding toward zero, reporting an error if
927    /// `value` is out of range.
928    fn try_from(value: f32) -> Result<Self, Self::Error> {
929        cast(value as f64 * Self::scale() as f64)
930            .and_then(Self::try_new)
931            .ok_or(OutOfRange)
932    }
933}
934
935impl<const P: usize, const S: usize> From<Fixed<P, S>> for f64 {
936    fn from(value: Fixed<P, S>) -> Self {
937        value.0 as f64 / Fixed::<P, S>::scale() as f64
938    }
939}
940
941impl<const P: usize, const S: usize> TryFrom<i128> for Fixed<P, S> {
942    type Error = OutOfRange;
943
944    /// Convert `value` to `Fixed`, reporting an error if `value` is out of
945    /// range.  This is an exact conversion that cannot lose precision if it
946    /// succeeds.
947    fn try_from(value: i128) -> Result<Self, Self::Error> {
948        if value.unsigned_abs() <= Self::max_u128() {
949            Ok(Self(value * Self::scale()))
950        } else {
951            Err(OutOfRange)
952        }
953    }
954}
955
956macro_rules! try_from_signed_int {
957    ($type_name:ty) => {
958        impl<const P: usize, const S: usize> TryFrom<$type_name> for Fixed<P, S> {
959            type Error = OutOfRange;
960
961            /// Convert `value` to `Fixed`, rounding toward zero, reporting an
962            /// error if `value` is out of range.
963            fn try_from(value: $type_name) -> Result<Self, Self::Error> {
964                (value as i128).try_into()
965            }
966        }
967    };
968}
969
970try_from_signed_int!(isize);
971try_from_signed_int!(i64);
972try_from_signed_int!(i32);
973try_from_signed_int!(i16);
974try_from_signed_int!(i8);
975
976impl<const P: usize, const S: usize> TryFrom<u128> for Fixed<P, S> {
977    type Error = OutOfRange;
978
979    /// Convert `value` to `Fixed`, reporting an error if `value` is out of
980    /// range.  This is an exact conversion that cannot lose precision if it
981    /// succeeds.
982    fn try_from(value: u128) -> Result<Self, Self::Error> {
983        if value <= Self::max_i128() as u128 {
984            Ok(Self(value as i128 * Self::scale()))
985        } else {
986            Err(OutOfRange)
987        }
988    }
989}
990
991macro_rules! try_from_unsigned_int {
992    ($type_name:ty) => {
993        impl<const P: usize, const S: usize> TryFrom<$type_name> for Fixed<P, S> {
994            type Error = OutOfRange;
995
996            /// Convert `value` to `Fixed`, reporting an error if `value` is out
997            /// of range.  This is an exact conversion that cannot lose
998            /// precision if it succeeds.
999            fn try_from(value: $type_name) -> Result<Self, Self::Error> {
1000                (value as u128).try_into()
1001            }
1002        }
1003    };
1004}
1005
1006try_from_unsigned_int!(usize);
1007try_from_unsigned_int!(u64);
1008try_from_unsigned_int!(u32);
1009try_from_unsigned_int!(u16);
1010try_from_unsigned_int!(u8);
1011
1012macro_rules! min_max_int {
1013    ($signed_type:ty, $max_signed:ident, $min_signed:ident, $unsigned_type:ty, $max_unsigned:ident) => {
1014        #[doc = "Returns the maximum `"]
1015        #[doc = stringify!($signed_type)]
1016        #[doc = "` that can be converted to this type."]
1017        pub const fn $max_signed() -> $signed_type {
1018            if Self::max_i128() > <$signed_type>::MAX as i128 {
1019                <$signed_type>::MAX
1020            } else {
1021                Self::max_i128() as $signed_type
1022            }
1023        }
1024
1025        #[doc = "Returns the minimum `"]
1026        #[doc = stringify!($signed_type)]
1027        #[doc = "` that can be converted to this type."]
1028        pub const fn $min_signed() -> $signed_type {
1029            -Self::$max_signed()
1030        }
1031
1032        #[doc = "Returns the maximum `"]
1033        #[doc = stringify!($unsigned_type)]
1034        #[doc = "` that can be converted to this type.\n\nThe minimum is 0."]
1035        pub const fn $max_unsigned() -> $unsigned_type {
1036            if Self::max_u128() > <$unsigned_type>::MAX as u128 {
1037                <$unsigned_type>::MAX
1038            } else {
1039                Self::max_u128() as $unsigned_type
1040            }
1041        }
1042    };
1043}
1044
1045impl<const P: usize, const S: usize> Fixed<P, S> {
1046    /// Returns the maximum `i128` that can be converted to this type.
1047    pub const fn max_i128() -> i128 {
1048        if P > S { pow10(P - S) - 1 } else { 0 }
1049    }
1050
1051    /// Returns the minimum `i128` that can be converted to this type.
1052    pub const fn min_i128() -> i128 {
1053        -Self::max_i128()
1054    }
1055
1056    /// Returns the maximum `u128` that can be converted to this type.
1057    ///
1058    /// The minimum is 0.
1059    pub const fn max_u128() -> u128 {
1060        Self::max_i128().cast_unsigned()
1061    }
1062
1063    min_max_int!(isize, max_isize, min_isize, usize, max_usize);
1064    min_max_int!(i64, max_i64, min_i64, u64, max_u64);
1065    min_max_int!(i32, max_i32, min_i32, u32, max_u32);
1066    min_max_int!(i16, max_i16, min_i16, u16, max_u16);
1067    min_max_int!(i8, max_i8, min_i8, u8, max_u8);
1068}
1069
1070impl<const P: usize, const S: usize> From<Fixed<P, S>> for i128 {
1071    /// Convert from `Fixed` to integer, rounding toward zero (the same
1072    /// semantics as Rust casts from float to integer).
1073    fn from(value: Fixed<P, S>) -> Self {
1074        // Integer `/` rounds toward zero in Rust.
1075        value.0 / <Fixed<P, S>>::scale()
1076    }
1077}
1078
1079macro_rules! try_to_signed_int {
1080    ($type_name:ty) => {
1081        impl<const P: usize, const S: usize> TryFrom<Fixed<P, S>> for $type_name {
1082            type Error = OutOfRange;
1083
1084            /// Convert from `Fixed` to integer, rounding toward zero (the same
1085            /// semantics as Rust casts from float to integer).
1086            fn try_from(value: Fixed<P, S>) -> Result<Self, Self::Error> {
1087                i128::from(value).try_into().map_err(|_| OutOfRange)
1088            }
1089        }
1090    };
1091}
1092
1093try_to_signed_int!(i64);
1094try_to_signed_int!(i32);
1095try_to_signed_int!(i16);
1096try_to_signed_int!(i8);
1097try_to_signed_int!(isize);
1098
1099/// This is the same as [try_to_signed_int] except for the documentation
1100/// comment.
1101macro_rules! try_to_unsigned_int {
1102    ($type_name:ty) => {
1103        impl<const P: usize, const S: usize> TryFrom<Fixed<P, S>> for $type_name {
1104            type Error = OutOfRange;
1105
1106            /// Convert from `Fixed` to integer, rounding toward zero (the same
1107            /// semantics as Rust casts from float to integer).
1108            ///
1109            /// Because this rounds toward zero, negative values greater than -1
1110            /// will convert to 0 instead of an out-of-range error.
1111            fn try_from(value: Fixed<P, S>) -> Result<Self, Self::Error> {
1112                i128::from(value).try_into().map_err(|_| OutOfRange)
1113            }
1114        }
1115    };
1116}
1117
1118try_to_unsigned_int!(u128);
1119try_to_unsigned_int!(u64);
1120try_to_unsigned_int!(u32);
1121try_to_unsigned_int!(u16);
1122try_to_unsigned_int!(u8);
1123try_to_unsigned_int!(usize);
1124
1125impl<const P: usize, const S: usize> Add for Fixed<P, S> {
1126    type Output = Self;
1127
1128    /// Returns the sum, rounding toward zero.
1129    ///
1130    /// # Panic
1131    ///
1132    /// Panics if the result is out of range.
1133    fn add(self, other: Self) -> Self::Output {
1134        self.checked_add(&other).unwrap()
1135    }
1136}
1137
1138impl<const P: usize, const S: usize> Add for &Fixed<P, S> {
1139    type Output = Fixed<P, S>;
1140
1141    /// Returns the sum, which is exact if the result is in range.
1142    ///
1143    /// # Panic
1144    ///
1145    /// Panics if the result is out of range.
1146    fn add(self, other: Self) -> Self::Output {
1147        self.checked_add(other).unwrap()
1148    }
1149}
1150
1151impl<const P: usize, const S: usize> CheckedAdd for Fixed<P, S> {
1152    /// Returns the sum, which is exact, or `None` if the result is out of
1153    /// range.
1154    fn checked_add(&self, other: &Self) -> Option<Self> {
1155        self.checked_add_generic(*other)
1156    }
1157}
1158
1159impl<const P: usize, const S: usize> AddAssign for Fixed<P, S> {
1160    /// Adds `other` to `self`, which is an exact calculation.
1161    ///
1162    /// # Panic
1163    ///
1164    /// Panics if the result is out of range.
1165    fn add_assign(&mut self, other: Self) {
1166        *self = *self + other;
1167    }
1168}
1169
1170impl<const P: usize, const S: usize> AddAssign<&Fixed<P, S>> for Fixed<P, S> {
1171    /// Adds `other` to `self`, which is an exact calculation.
1172    ///
1173    /// # Panic
1174    ///
1175    /// Panics if the result is out of range.
1176    fn add_assign(&mut self, other: &Fixed<P, S>) {
1177        *self = *self + *other;
1178    }
1179}
1180
1181impl<const P: usize, const S: usize> Sub for Fixed<P, S> {
1182    type Output = Self;
1183
1184    /// Returns the difference, which is exact if the result is in range.
1185    ///
1186    /// # Panic
1187    ///
1188    /// Panics if the result is out of range.
1189    fn sub(self, other: Self) -> Self::Output {
1190        self.checked_sub(&other).unwrap()
1191    }
1192}
1193
1194impl<const P: usize, const S: usize> Sub for &Fixed<P, S> {
1195    type Output = Fixed<P, S>;
1196
1197    /// Returns the difference, which is exact if the result is in range.
1198    ///
1199    /// # Panic
1200    ///
1201    /// Panics if the result is out of range.
1202    fn sub(self, other: Self) -> Self::Output {
1203        self.checked_sub(other).unwrap()
1204    }
1205}
1206
1207impl<const P: usize, const S: usize> CheckedSub for Fixed<P, S> {
1208    /// Returns the difference, which is exact, or `None` if the result is out
1209    /// of range.
1210    fn checked_sub(&self, other: &Self) -> Option<Self> {
1211        self.checked_sub_generic(*other)
1212    }
1213}
1214
1215impl<const P: usize, const S: usize> SubAssign for Fixed<P, S> {
1216    /// Subtracts `other` from `self`, which is an exact calculation.
1217    ///
1218    /// # Panic
1219    ///
1220    /// Panics if the result is out of range.
1221    fn sub_assign(&mut self, other: Self) {
1222        *self = *self - other;
1223    }
1224}
1225
1226impl<const P: usize, const S: usize> Mul for Fixed<P, S> {
1227    type Output = Self;
1228
1229    /// Returns the product, rounding toward zero.
1230    ///
1231    /// # Panic
1232    ///
1233    /// Panics if the result is out of range.
1234    fn mul(self, other: Self) -> Self::Output {
1235        self.checked_mul(&other).unwrap()
1236    }
1237}
1238
1239impl<const P: usize, const S: usize> Mul for &Fixed<P, S> {
1240    type Output = Fixed<P, S>;
1241
1242    /// Returns the product, rounding toward zero.
1243    ///
1244    /// # Panic
1245    ///
1246    /// Panics if the result is out of range.
1247    fn mul(self, other: Self) -> Self::Output {
1248        self.checked_mul(other).unwrap()
1249    }
1250}
1251
1252impl<const P: usize, const S: usize> CheckedMul for Fixed<P, S> {
1253    /// Returns the product, rounding toward zero, or `None` if the result is
1254    /// out of range.
1255    fn checked_mul(&self, other: &Self) -> Option<Self> {
1256        Self::checked_mul_generic(*self, *other)
1257    }
1258}
1259
1260impl<const P: usize, const S: usize> MulAssign for Fixed<P, S> {
1261    /// Multiplies `self` by `other`, rounding toward zero.
1262    ///
1263    /// # Panic
1264    ///
1265    /// Panics if the result is out of range.
1266    fn mul_assign(&mut self, other: Self) {
1267        *self = *self * other;
1268    }
1269}
1270
1271impl<const P: usize, const S: usize> Div for Fixed<P, S> {
1272    type Output = Self;
1273
1274    /// Returns the quotient, rounding toward zero.
1275    ///
1276    /// # Panic
1277    ///
1278    /// Panics if `other` is zero or the result is out of range.
1279    fn div(self, other: Self) -> Self::Output {
1280        self.checked_div(&other).unwrap()
1281    }
1282}
1283
1284impl<const P: usize, const S: usize> Div for &Fixed<P, S> {
1285    type Output = Fixed<P, S>;
1286
1287    /// Returns the quotient, rounding toward zero.
1288    ///
1289    /// # Panic
1290    ///
1291    /// Panics if `other` is zero or the result is out of range.
1292    fn div(self, other: Self) -> Self::Output {
1293        self.checked_div(other).unwrap()
1294    }
1295}
1296
1297impl<const P: usize, const S: usize> CheckedDiv for Fixed<P, S> {
1298    /// Returns the quotient, rounding toward zero, or `None` if `other` is zero
1299    /// or the result is out of range.
1300    fn checked_div(&self, other: &Self) -> Option<Self> {
1301        Self::checked_div_generic(*self, *other)
1302    }
1303}
1304
1305impl<const P: usize, const S: usize> DivAssign for Fixed<P, S> {
1306    /// Divides `self` by `other`, rounding toward zero.
1307    ///
1308    /// # Panic
1309    ///
1310    /// Panics if `other` is zero or the result is out of range.
1311    fn div_assign(&mut self, other: Self) {
1312        *self = *self / other;
1313    }
1314}
1315
1316impl<const P: usize, const S: usize> Neg for Fixed<P, S> {
1317    type Output = Self;
1318
1319    /// Returns `-self`.  This is an exact calculation that cannot overflow.
1320    fn neg(self) -> Self::Output {
1321        Self(-self.0)
1322    }
1323}
1324
1325impl<const P: usize, const S: usize> Neg for &Fixed<P, S> {
1326    type Output = Fixed<P, S>;
1327
1328    /// Returns `-self`.  This is an exact calculation that cannot overflow.
1329    fn neg(self) -> Self::Output {
1330        Fixed(-self.0)
1331    }
1332}
1333
1334impl<const P: usize, const S: usize> FromStr for Fixed<P, S> {
1335    type Err = ParseDecimalError;
1336
1337    /// Parses `s` as `Fixed`.
1338    ///
1339    /// This accepts the same forms as [f64::from_str], except that it rejects
1340    /// infinities and NaNs (which `Fixed` does not support), as well as
1341    /// out-of-range values.  Rounds overprecise values to the nearest
1342    /// representable value, rounding halfway values to even.
1343    fn from_str(s: &str) -> Result<Self, Self::Err> {
1344        let (value, exponent) = parse_decimal(s, S as i32)?;
1345        Self::try_new_with_exponent_round_even(value, exponent).ok_or(ParseDecimalError::OutOfRange)
1346    }
1347}
1348
1349impl<const P: usize, const S: usize> Debug for Fixed<P, S> {
1350    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1351        debug_decimal(self.0, S, f)
1352    }
1353}
1354
1355impl<const P: usize, const S: usize> Display for Fixed<P, S> {
1356    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1357        display_decimal(self.0, S, f)
1358    }
1359}
1360
1361impl<const P: usize, const S: usize> Fixed<P, S> {
1362    /// Value returned by `Self::MIN.to_unsigned_encoding()`.
1363    ///
1364    /// This is always 0.
1365    pub const UNSIGNED_MIN: u128 = 0;
1366
1367    /// Value returned by `Self::ZERO.to_unsigned_encoding()`.
1368    pub const UNSIGNED_ZERO: u128 = pow10(P).cast_unsigned() - 1;
1369
1370    /// Value returned by `Self::MAX.to_unsigned_encoding()`.
1371    pub const UNSIGNED_MAX: u128 = pow10(P).cast_unsigned() * 2 - 2;
1372
1373    /// Returns this value converted to a `u128` in the range
1374    /// [`Self::UNSIGNED_MIN`] to [`Self::UNSIGNED_MAX`] (inclusive).  The
1375    /// values returned for any given [`Fixed<P,S>`] are suitable for equality
1376    /// and order comparison, that is, `a.cmp(&b)` has the same value as
1377    /// `a.to_unsigned_encoding().cmp(&b.to_unsigned_encoding())`.
1378    ///
1379    /// # Usage
1380    ///
1381    /// This might only be useful in practice for [DBSP] aggregates, which only
1382    /// only support unsigned integer values.  We expose it in case it's useful
1383    /// for some other purpose.
1384    ///
1385    /// [DBSP]: https://docs.rs/dbsp/latest/dbsp/
1386    pub fn to_unsigned_encoding(self) -> u128 {
1387        Self::UNSIGNED_ZERO.checked_add_signed(self.0).unwrap()
1388    }
1389
1390    /// Inverts the transformation of [`to_unsigned_encoding`], returning the
1391    /// original `Fixed` value (assuming `P` and `S` are the same as before).
1392    /// Returns `None` if `encoding` is invalid (which cannot happen if
1393    /// [`to_unsigned_encoding`] returned `encoding`).
1394    ///
1395    /// [`to_unsigned_encoding`]: Self::to_unsigned_encoding
1396    ///
1397    /// # Usage
1398    ///
1399    /// This might only be useful in practice for [DBSP] aggregates, which only
1400    /// only support unsigned integer values.  We expose it in case it's useful
1401    /// for some other purpose.
1402    ///
1403    /// [DBSP]: https://docs.rs/dbsp/latest/dbsp/
1404    pub fn from_unsigned_encoding(encoding: u128) -> Option<Self> {
1405        if encoding < Self::UNSIGNED_ZERO {
1406            Some(Self(-(Self::UNSIGNED_ZERO - encoding).cast_signed()))
1407        } else if encoding <= Self::UNSIGNED_MAX {
1408            Some(Self((encoding - Self::UNSIGNED_ZERO).cast_signed()))
1409        } else {
1410            None
1411        }
1412    }
1413}
1414
1415#[cfg(test)]
1416mod test {
1417    use std::str::FromStr;
1418
1419    use num_traits::{CheckedAdd, CheckedDiv, CheckedMul, CheckedSub};
1420
1421    use crate::Fixed;
1422
1423    type F = Fixed<10, 2>;
1424    fn f(n: f64) -> F {
1425        Fixed::try_from(n).unwrap()
1426    }
1427
1428    fn f38_0(n: f64) -> Fixed<38, 0> {
1429        Fixed::try_from(n).unwrap()
1430    }
1431
1432    fn f38_38(s: &str) -> Fixed<38, 38> {
1433        Fixed::from_str(s).unwrap()
1434    }
1435
1436    #[test]
1437    fn mul() {
1438        // A few specific handwritten cases.
1439        assert_eq!(f(1.23) * f(2.34), f(2.87));
1440        assert_eq!(f(-1.23) * f(2.34), f(-2.87));
1441        assert_eq!(f(1.23) * f(-2.34), f(-2.87));
1442        assert_eq!(f(-1.23) * f(-2.34), f(2.87));
1443
1444        // General case.
1445        for a in -999..=999 {
1446            let af: Fixed<10, 2> = Fixed(a);
1447            for b in -999..=999 {
1448                let bf: Fixed<10, 2> = Fixed(b);
1449                assert_eq!(af * bf, Fixed::<10, 2>(a * b / 100));
1450            }
1451        }
1452
1453        // General case with overflow.
1454        for a in -999..=999 {
1455            let af: Fixed<3, 2> = Fixed(a);
1456            for b in -999..=999 {
1457                let bf: Fixed<3, 2> = Fixed(b);
1458                let c = a * b / 100;
1459                let expected = (c.unsigned_abs() < 1000).then_some(Fixed(c));
1460                assert_eq!(af.checked_mul(&bf), expected);
1461            }
1462        }
1463    }
1464
1465    #[test]
1466    fn mul_generic() {
1467        for a in -999..=999 {
1468            let af: Fixed<10, 2> = Fixed(a);
1469            for b in -999..=999 {
1470                let bf: Fixed<10, 3> = Fixed(b);
1471                let cf: Fixed<10, 5> = af.checked_mul_generic(bf).unwrap();
1472                assert_eq!(cf, Fixed::<10, 5>(a * b));
1473                let df: Fixed<10, 6> = af.checked_mul_generic(bf).unwrap();
1474                assert_eq!(df, Fixed::<10, 6>(a * b * 10));
1475                let ef: Fixed<10, 0> = af.checked_mul_generic(bf).unwrap();
1476                assert_eq!(ef, Fixed::<10, 0>(a * b / 100_000));
1477            }
1478        }
1479    }
1480
1481    #[test]
1482    fn div() {
1483        // A few specific handwritten cases.
1484        assert_eq!(f(1.23) / f(2.34), f(0.52));
1485        assert_eq!(f(-1.23) / f(2.34), f(-0.52));
1486        assert_eq!(f(1.23) / f(-2.34), f(-0.52));
1487        assert_eq!(f(-1.23) / f(-2.34), f(0.52));
1488        assert_eq!(
1489            f38_0(1.0)
1490                .checked_div_generic::<38, 0, 38, 38>(f38_0(7.0))
1491                .unwrap(),
1492            f38_38("0.14285714285714285714285714285714285714")
1493        );
1494
1495        assert_eq!(
1496            f38_0(123.0).checked_div_generic::<38, 38, 38, 38>(f38_38("0.456")),
1497            None
1498        );
1499
1500        // General case.
1501        for a in -999..=999 {
1502            let af: Fixed<10, 2> = Fixed(a);
1503            for b in -999..=999 {
1504                let bf: Fixed<10, 2> = Fixed(b);
1505                assert_eq!(af.checked_div(&bf), (b != 0).then(|| Fixed(a * 100 / b)));
1506            }
1507        }
1508
1509        // General case with overflow.
1510        for a in -999..=999 {
1511            let af: Fixed<3, 2> = Fixed(a);
1512            for b in -999..=999 {
1513                let bf: Fixed<3, 2> = Fixed(b);
1514                let expected = if b != 0 {
1515                    let result = a * 100 / b;
1516                    (result.unsigned_abs() <= 999).then_some(Fixed(result))
1517                } else {
1518                    None
1519                };
1520                assert_eq!(af.checked_div(&bf), expected);
1521            }
1522        }
1523    }
1524
1525    #[test]
1526    fn div_generic() {
1527        fn test<const P: usize, const S: usize>(a: i128, af: Fixed<P, S>) {
1528            for b in -999..=999 {
1529                if b != 0 {
1530                    let bf: Fixed<10, 3> = Fixed(b);
1531                    let cf: Fixed<10, 5> = af.checked_div_generic(bf).unwrap();
1532                    assert_eq!(cf, Fixed::<10, 5>(a * 1_000_000 / b));
1533                    let df: Fixed<10, 6> = af.checked_div_generic(bf).unwrap();
1534                    assert_eq!(df, Fixed::<10, 6>(a * 10_000_000 / b));
1535                    let ef: Fixed<10, 0> = af.checked_div_generic(bf).unwrap();
1536                    assert_eq!(ef, Fixed::<10, 0>(a * 10 / b));
1537                }
1538            }
1539        }
1540
1541        for a in -999..=999 {
1542            let af: Fixed<10, 2> = Fixed(a);
1543            test(a, af);
1544            let af2: Fixed<18, 10> = af.convert().unwrap();
1545            test(a, af2);
1546        }
1547    }
1548
1549    #[test]
1550    fn add() {
1551        // A few specific handwritten cases.
1552        assert_eq!(f(1.23) + f(2.34), f(3.57));
1553        assert_eq!(f(-1.23) + f(2.34), f(1.11));
1554        assert_eq!(f(1.23) + f(-2.34), f(-1.11));
1555        assert_eq!(f(-1.23) + f(-2.34), f(-3.57));
1556
1557        // Cases that require avoiding intermediate overflow.
1558        let af: Fixed<38, 35> = Fixed::try_from(999).unwrap();
1559        let bf: Fixed<37, 34> = Fixed::try_from(999).unwrap();
1560        let cf: Fixed<36, 30> = af.checked_add_generic(bf).unwrap();
1561        assert_eq!(cf, 1998);
1562        let df: Fixed<36, 30> = bf.checked_add_generic(af).unwrap();
1563        assert_eq!(df, 1998);
1564        let ef: Fixed<36, 3> = af.checked_add_generic(af).unwrap();
1565        assert_eq!(ef, 1998);
1566        let ff: Option<Fixed<38, 35>> = af.checked_add_generic(af);
1567        assert_eq!(ff, None);
1568
1569        // General case.
1570        for a in -999..=999 {
1571            let af: Fixed<10, 2> = Fixed(a);
1572            for b in -999..=999 {
1573                let bf: Fixed<10, 2> = Fixed(b);
1574                assert_eq!(af + bf, Fixed::<10, 2>(a + b));
1575            }
1576        }
1577
1578        // General case with overflow.
1579        for a in -999..=999 {
1580            let af: Fixed<3, 2> = Fixed(a);
1581            for b in -999..=999 {
1582                let bf: Fixed<3, 2> = Fixed(b);
1583                let c = a + b;
1584                let expected = (c.unsigned_abs() < 1000).then_some(Fixed(c));
1585                assert_eq!(af.checked_add(&bf), expected);
1586            }
1587        }
1588
1589        // General case with type conversion.
1590        for a in -999..=999 {
1591            let af: Fixed<10, 2> = Fixed(a);
1592            for b in -999..=999 {
1593                let bf: Fixed<10, 3> = Fixed(b);
1594                let cf: Fixed<10, 5> = af.checked_add_generic(bf).unwrap();
1595                assert_eq!(
1596                    cf,
1597                    Fixed::<10, 5>(a * 1000 + b * 100),
1598                    "{af} + {bf} ?= {cf}"
1599                );
1600                let cf: Fixed<10, 5> = bf.checked_add_generic(af).unwrap();
1601                assert_eq!(
1602                    cf,
1603                    Fixed::<10, 5>(a * 1000 + b * 100),
1604                    "{bf} + {af} ?= {cf}"
1605                );
1606                let df: Fixed<10, 6> = af.checked_add_generic(bf).unwrap();
1607                assert_eq!(
1608                    df,
1609                    Fixed::<10, 6>(a * 10_000 + b * 1000),
1610                    "{af} + {bf} ?= {df}"
1611                );
1612                let ef: Fixed<10, 0> = af.checked_add_generic(bf).unwrap();
1613                assert_eq!(
1614                    ef,
1615                    Fixed::<10, 0>((a * 10 + b) / 1000),
1616                    "{af} + {bf} ?= {ef}"
1617                );
1618
1619                let ff: Fixed<10, 2> = Fixed(b);
1620                let gf: Fixed<10, 1> = af.checked_add_generic(ff).unwrap();
1621                assert_eq!(gf, Fixed::<10, 1>((a + b) / 10), "{af} + {ff} ?= {gf}");
1622                let hf: Fixed<10, 3> = af.checked_add_generic(ff).unwrap();
1623                assert_eq!(hf, Fixed::<10, 3>((a + b) * 10), "{af} + {ff} ?= {hf}");
1624            }
1625        }
1626    }
1627
1628    #[test]
1629    fn sub() {
1630        // A few specific handwritten cases.
1631        assert_eq!(f(1.23) - f(2.34), f(-1.11));
1632        assert_eq!(f(-1.23) - f(2.34), f(-3.57));
1633        assert_eq!(f(1.23) - f(-2.34), f(3.57));
1634        assert_eq!(f(-1.23) - f(-2.34), f(1.11));
1635
1636        // General case.
1637        for a in -999..=999 {
1638            let af: Fixed<10, 2> = Fixed(a);
1639            for b in -999..=999 {
1640                let bf: Fixed<10, 2> = Fixed(b);
1641                assert_eq!(af - bf, Fixed::<10, 2>(a - b));
1642            }
1643        }
1644
1645        // General case with overflow.
1646        for a in -999..=999 {
1647            let af: Fixed<3, 2> = Fixed(a);
1648            for b in -999..=999 {
1649                let bf: Fixed<3, 2> = Fixed(b);
1650                let c = a - b;
1651                let expected = (c.unsigned_abs() < 1000).then_some(Fixed(c));
1652                assert_eq!(af.checked_sub(&bf), expected);
1653            }
1654        }
1655
1656        // General case with type conversion.
1657        for a in -999..=999 {
1658            let af: Fixed<10, 2> = Fixed(a);
1659            for b in -999..=999 {
1660                let bf: Fixed<10, 3> = Fixed(b);
1661                let cf: Fixed<10, 5> = af.checked_sub_generic(bf).unwrap();
1662                assert_eq!(
1663                    cf,
1664                    Fixed::<10, 5>(a * 1000 - b * 100),
1665                    "{af} - {bf} ?= {cf}"
1666                );
1667                let cf: Fixed<10, 5> = bf.checked_sub_generic(af).unwrap();
1668                assert_eq!(
1669                    cf,
1670                    Fixed::<10, 5>(b * 100 - a * 1000),
1671                    "{bf} - {af} ?= {cf}"
1672                );
1673                let df: Fixed<10, 6> = af.checked_sub_generic(bf).unwrap();
1674                assert_eq!(df, Fixed::<10, 6>(a * 10_000 - b * 1000));
1675            }
1676        }
1677    }
1678
1679    #[test]
1680    fn powi() {
1681        assert_eq!(
1682            Fixed::<10, 8>::from_str("1.12345678")
1683                .unwrap()
1684                .powi(8)
1685                .to_string()
1686                .as_str(),
1687            "2.53776238"
1688        );
1689        assert_eq!(f(2.0).powi(3), f(8.0));
1690        assert_eq!(f(-2.0).powi(3), f(-8.0));
1691        assert_eq!(f(1.7).powi(8), f(69.75));
1692        assert_eq!(f(1.7).powi(-8), f(0.01));
1693        assert_eq!(f(0.0).powi(1), f(0.0));
1694        assert_eq!(f(0.0).checked_powi(0), None);
1695        assert_eq!(f(0.0).checked_powi(-1), None);
1696    }
1697
1698    #[test]
1699    fn convert() {
1700        let a = Fixed::<10, 10>::from_str("0.0123456789").unwrap();
1701        assert_eq!(&a.convert::<10, 0>().unwrap().to_string(), "0");
1702        assert_eq!(&a.convert::<10, 1>().unwrap().to_string(), "0");
1703        assert_eq!(&a.convert::<10, 2>().unwrap().to_string(), "0.01");
1704        assert_eq!(&a.convert::<10, 3>().unwrap().to_string(), "0.012");
1705        assert_eq!(&a.convert::<10, 4>().unwrap().to_string(), "0.0123");
1706        assert_eq!(&a.convert::<10, 5>().unwrap().to_string(), "0.01234");
1707        assert_eq!(&a.convert::<10, 6>().unwrap().to_string(), "0.012345");
1708        assert_eq!(&a.convert::<10, 7>().unwrap().to_string(), "0.0123456");
1709        assert_eq!(&a.convert::<10, 8>().unwrap().to_string(), "0.01234567");
1710        assert_eq!(&a.convert::<10, 9>().unwrap().to_string(), "0.012345678");
1711        assert_eq!(&a.convert::<10, 10>().unwrap().to_string(), "0.0123456789");
1712        assert_eq!(&a.convert_round_even::<10, 0>().unwrap().to_string(), "0");
1713        assert_eq!(&a.convert_round_even::<10, 1>().unwrap().to_string(), "0");
1714        assert_eq!(
1715            &a.convert_round_even::<10, 2>().unwrap().to_string(),
1716            "0.01"
1717        );
1718        assert_eq!(
1719            &a.convert_round_even::<10, 3>().unwrap().to_string(),
1720            "0.012"
1721        );
1722        assert_eq!(
1723            &a.convert_round_even::<10, 4>().unwrap().to_string(),
1724            "0.0123"
1725        );
1726        assert_eq!(
1727            &a.convert_round_even::<10, 5>().unwrap().to_string(),
1728            "0.01235"
1729        );
1730        assert_eq!(
1731            &a.convert_round_even::<10, 6>().unwrap().to_string(),
1732            "0.012346"
1733        );
1734        assert_eq!(
1735            &a.convert_round_even::<10, 7>().unwrap().to_string(),
1736            "0.0123457"
1737        );
1738        assert_eq!(
1739            &a.convert_round_even::<10, 8>().unwrap().to_string(),
1740            "0.01234568"
1741        );
1742        assert_eq!(
1743            &a.convert_round_even::<10, 9>().unwrap().to_string(),
1744            "0.012345679"
1745        );
1746        assert_eq!(
1747            &a.convert_round_even::<10, 10>().unwrap().to_string(),
1748            "0.0123456789"
1749        );
1750
1751        let b = Fixed::<10, 5>::from_str("12345.67895").unwrap();
1752        assert_eq!(&b.convert::<10, 0>().unwrap().to_string(), "12345");
1753        assert_eq!(&b.convert::<10, 1>().unwrap().to_string(), "12345.6");
1754        assert_eq!(&b.convert::<10, 2>().unwrap().to_string(), "12345.67");
1755        assert_eq!(&b.convert::<10, 3>().unwrap().to_string(), "12345.678");
1756        assert_eq!(&b.convert::<10, 4>().unwrap().to_string(), "12345.6789");
1757        assert_eq!(&b.convert::<10, 5>().unwrap().to_string(), "12345.67895");
1758        assert_eq!(b.convert::<10, 6>(), None);
1759        assert_eq!(b.convert::<10, 7>(), None);
1760        assert_eq!(b.convert::<10, 8>(), None);
1761        assert_eq!(b.convert::<10, 9>(), None);
1762        assert_eq!(b.convert::<10, 10>(), None);
1763        assert_eq!(
1764            &b.convert_round_even::<10, 0>().unwrap().to_string(),
1765            "12346"
1766        );
1767        assert_eq!(
1768            &b.convert_round_even::<10, 1>().unwrap().to_string(),
1769            "12345.7"
1770        );
1771        assert_eq!(
1772            &b.convert_round_even::<10, 2>().unwrap().to_string(),
1773            "12345.68"
1774        );
1775        assert_eq!(
1776            &b.convert_round_even::<10, 3>().unwrap().to_string(),
1777            "12345.679"
1778        );
1779        assert_eq!(
1780            &b.convert_round_even::<10, 4>().unwrap().to_string(),
1781            "12345.679"
1782        );
1783        assert_eq!(
1784            &b.convert_round_even::<10, 5>().unwrap().to_string(),
1785            "12345.67895"
1786        );
1787        assert_eq!(b.convert_round_even::<10, 6>(), None);
1788        assert_eq!(b.convert_round_even::<10, 7>(), None);
1789        assert_eq!(b.convert_round_even::<10, 8>(), None);
1790        assert_eq!(b.convert_round_even::<10, 9>(), None);
1791        assert_eq!(b.convert_round_even::<10, 10>(), None);
1792    }
1793
1794    #[test]
1795    fn constants() {
1796        assert_eq!(Fixed::<5, 0>::MAX, Fixed::<5, 0>(99999));
1797        assert_eq!(Fixed::<5, 0>::MIN, Fixed::<5, 0>(-99999));
1798        assert_eq!(Fixed::<5, 0>::ZERO, Fixed::<5, 0>(0));
1799        assert_eq!(Fixed::<5, 0>::ONE, Fixed::<5, 0>(1));
1800
1801        assert_eq!(Fixed::<5, 1>::MAX, Fixed::<5, 1>(99999));
1802        assert_eq!(Fixed::<5, 1>::MIN, Fixed::<5, 1>(-99999));
1803        assert_eq!(Fixed::<5, 1>::ZERO, Fixed::<5, 1>(0));
1804        assert_eq!(Fixed::<5, 1>::ONE, Fixed::<5, 1>(10));
1805
1806        assert_eq!(Fixed::<5, 2>::MAX, Fixed::<5, 2>(99999));
1807        assert_eq!(Fixed::<5, 2>::MIN, Fixed::<5, 2>(-99999));
1808        assert_eq!(Fixed::<5, 2>::ZERO, Fixed::<5, 2>(0));
1809        assert_eq!(Fixed::<5, 2>::ONE, Fixed::<5, 2>(100));
1810
1811        assert_eq!(Fixed::<5, 3>::MAX, Fixed::<5, 3>(99999));
1812        assert_eq!(Fixed::<5, 3>::MIN, Fixed::<5, 3>(-99999));
1813        assert_eq!(Fixed::<5, 3>::ZERO, Fixed::<5, 3>(0));
1814        assert_eq!(Fixed::<5, 3>::ONE, Fixed::<5, 3>(1000));
1815
1816        assert_eq!(Fixed::<5, 4>::MAX, Fixed::<5, 4>(99999));
1817        assert_eq!(Fixed::<5, 4>::MIN, Fixed::<5, 4>(-99999));
1818        assert_eq!(Fixed::<5, 4>::ZERO, Fixed::<5, 4>(0));
1819        assert_eq!(Fixed::<5, 4>::ONE, Fixed::<5, 4>(10000));
1820
1821        assert_eq!(Fixed::<5, 5>::MAX, Fixed::<5, 5>(99999));
1822        assert_eq!(Fixed::<5, 5>::MIN, Fixed::<5, 5>(-99999));
1823        assert_eq!(Fixed::<5, 5>::ZERO, Fixed::<5, 5>(0));
1824        // This would panic at compile time.  See [super::_invalid_constant_test].
1825        //let _ = Fixed::<5, 5>::ONE;
1826    }
1827
1828    #[test]
1829    fn floor() {
1830        assert_eq!(f(5.0).floor(), f(5.0));
1831        assert_eq!(f(5.1).floor(), f(5.0));
1832        assert_eq!(f(5.5).floor(), f(5.0));
1833        assert_eq!(f(5.9).floor(), f(5.0));
1834        assert_eq!(f(-5.0).floor(), f(-5.0));
1835        assert_eq!(f(-5.1).floor(), f(-6.0));
1836        assert_eq!(f(-5.5).floor(), f(-6.0));
1837        assert_eq!(f(-5.6).floor(), f(-6.0));
1838        assert_eq!(f(4.0).floor(), f(4.0));
1839        assert_eq!(f(4.1).floor(), f(4.0));
1840        assert_eq!(f(4.5).floor(), f(4.0));
1841        assert_eq!(f(4.9).floor(), f(4.0));
1842        assert_eq!(f(-4.0).floor(), f(-4.0));
1843        assert_eq!(f(-4.1).floor(), f(-5.0));
1844        assert_eq!(f(-4.5).floor(), f(-5.0));
1845        assert_eq!(f(-4.6).floor(), f(-5.0));
1846        assert_eq!(f(-99_999_999.0).floor(), f(-99_999_999.0));
1847        assert_eq!(f(-99_999_999.1).checked_floor(), None);
1848        assert_eq!(f(-99_999_999.5).checked_floor(), None);
1849        assert_eq!(f(-99_999_999.6).checked_floor(), None);
1850    }
1851
1852    #[test]
1853    fn ceil() {
1854        assert_eq!(f(5.0).ceil(), f(5.0));
1855        assert_eq!(f(5.1).ceil(), f(6.0));
1856        assert_eq!(f(5.5).ceil(), f(6.0));
1857        assert_eq!(f(5.9).ceil(), f(6.0));
1858        assert_eq!(f(-5.0).ceil(), f(-5.0));
1859        assert_eq!(f(-5.1).ceil(), f(-5.0));
1860        assert_eq!(f(-5.5).ceil(), f(-5.0));
1861        assert_eq!(f(-5.6).ceil(), f(-5.0));
1862        assert_eq!(f(4.0).ceil(), f(4.0));
1863        assert_eq!(f(4.1).ceil(), f(5.0));
1864        assert_eq!(f(4.5).ceil(), f(5.0));
1865        assert_eq!(f(4.9).ceil(), f(5.0));
1866        assert_eq!(f(-4.0).ceil(), f(-4.0));
1867        assert_eq!(f(-4.1).ceil(), f(-4.0));
1868        assert_eq!(f(-4.5).ceil(), f(-4.0));
1869        assert_eq!(f(-4.6).ceil(), f(-4.0));
1870        assert_eq!(f(99_999_999.0).ceil(), f(99_999_999.0));
1871        assert_eq!(f(99_999_999.1).checked_ceil(), None);
1872        assert_eq!(f(99_999_999.5).checked_ceil(), None);
1873        assert_eq!(f(99_999_999.6).checked_ceil(), None);
1874    }
1875
1876    #[test]
1877    fn trunc() {
1878        fn test(x: f64, expected: f64) {
1879            assert_eq!(f(x).trunc(), f(expected));
1880            assert_eq!(f(x).trunc_digits(0), f(expected));
1881        }
1882
1883        test(5.0, 5.0);
1884        test(5.1, 5.0);
1885        test(5.5, 5.0);
1886        test(5.9, 5.0);
1887        test(-5.0, -5.0);
1888        test(-5.1, -5.0);
1889        test(-5.5, -5.0);
1890        test(-5.6, -5.0);
1891        test(4.0, 4.0);
1892        test(4.1, 4.0);
1893        test(4.5, 4.0);
1894        test(4.9, 4.0);
1895        test(-4.0, -4.0);
1896        test(-4.1, -4.0);
1897        test(-4.5, -4.0);
1898        test(-4.6, -4.0);
1899        test(99_999_999.0, 99_999_999.0);
1900        test(99_999_999.1, 99_999_999.0);
1901        test(99_999_999.5, 99_999_999.0);
1902        test(99_999_999.6, 99_999_999.0);
1903        test(-99_999_999.0, -99_999_999.0);
1904        test(-99_999_999.1, -99_999_999.0);
1905        test(-99_999_999.5, -99_999_999.0);
1906        test(-99_999_999.6, -99_999_999.0);
1907    }
1908
1909    #[test]
1910    fn round() {
1911        fn test(x: f64, expected: Option<f64>) {
1912            assert_eq!(f(x).checked_round(0), expected.map(f));
1913        }
1914        type F = Fixed<10, 2>;
1915        fn test1((x, s): (i128, i32), d: i32, expected: Option<(i128, i32)>) {
1916            assert_eq!(
1917                F::new(x, s).unwrap().checked_round(d),
1918                expected.map(|x| F::new(x.0, x.1).unwrap())
1919            );
1920        }
1921
1922        // round(5.1 , 2) = 5.1
1923        test1((51, 1), 2, Some((51, 1)));
1924        // round(5.1, 1) = 5.1
1925        test1((51, 1), 1, Some((51, 1)));
1926        // round(5.1, 0) = 5.0
1927        test1((51, 1), 0, Some((50, 1)));
1928        // round(5.1, -1) = 10
1929        test1((51, 1), -1, Some((10, 0)));
1930
1931        // round(2.1, 2) = 2.1
1932        test1((21, 1), 2, Some((21, 1)));
1933        // round(2.1, 1) = 2.1
1934        test1((21, 1), 1, Some((21, 1)));
1935        // round(2.1, 0) = 2.0
1936        test1((21, 1), 0, Some((20, 1)));
1937        // round(2.1, -1) = 0
1938        test1((21, 1), -1, Some((0, 0)));
1939
1940        // round(99_999_999.1, 2) = 99_999_999.1
1941        test1((999_999_991, 1), 2, Some((999_999_991, 1)));
1942        // round(99_999_999.1, 1) = 99_999_999.1
1943        test1((999_999_991, 1), 1, Some((999_999_991, 1)));
1944        // round(99_999_999.1, 0) = 99_999_999.0
1945        test1((999_999_991, 1), 0, Some((999_999_990, 1)));
1946        // round(99_999_999.1, -1) = None
1947        test1((999_999_991, 1), -1, None);
1948
1949        test(5.0, Some(5.0));
1950        test(5.1, Some(5.0));
1951        test(5.5, Some(6.0));
1952        test(5.9, Some(6.0));
1953        test(-5.0, Some(-5.0));
1954        test(-5.1, Some(-5.0));
1955        test(-5.5, Some(-6.0));
1956        test(-5.6, Some(-6.0));
1957        test(4.0, Some(4.0));
1958        test(4.1, Some(4.0));
1959        test(4.5, Some(5.0));
1960        test(4.9, Some(5.0));
1961        test(-4.0, Some(-4.0));
1962        test(-4.1, Some(-4.0));
1963        test(-4.5, Some(-5.0));
1964        test(-4.6, Some(-5.0));
1965        test(99_999_999.0, Some(99_999_999.0));
1966        test(99_999_999.1, Some(99_999_999.0));
1967        test(99_999_999.5, None);
1968        test(99_999_999.6, None);
1969        test(-99_999_999.0, Some(-99_999_999.0));
1970        test(-99_999_999.1, Some(-99_999_999.0));
1971        test(-99_999_999.5, None);
1972        test(-99_999_999.6, None);
1973    }
1974
1975    #[test]
1976    fn trunc_digits() {
1977        let x = Fixed::<10, 4>(245368746);
1978        assert_eq!(x.trunc_digits(5).to_string(), "24536.8746");
1979        assert_eq!(x.trunc_digits(4).to_string(), "24536.8746");
1980        assert_eq!(x.trunc_digits(3).to_string(), "24536.874");
1981        assert_eq!(x.trunc_digits(2).to_string(), "24536.87");
1982        assert_eq!(x.trunc_digits(1).to_string(), "24536.8");
1983        assert_eq!(x.trunc_digits(0).to_string(), "24536");
1984        assert_eq!(x.trunc_digits(-1).to_string(), "24530");
1985        assert_eq!(x.trunc_digits(-2).to_string(), "24500");
1986        assert_eq!(x.trunc_digits(-3).to_string(), "24000");
1987        assert_eq!(x.trunc_digits(-4).to_string(), "20000");
1988        assert_eq!(x.trunc_digits(-5).to_string(), "0");
1989        assert_eq!(x.trunc_digits(-50).to_string(), "0");
1990
1991        let x = -x;
1992        assert_eq!(x.trunc_digits(5).to_string(), "-24536.8746");
1993        assert_eq!(x.trunc_digits(4).to_string(), "-24536.8746");
1994        assert_eq!(x.trunc_digits(3).to_string(), "-24536.874");
1995        assert_eq!(x.trunc_digits(2).to_string(), "-24536.87");
1996        assert_eq!(x.trunc_digits(1).to_string(), "-24536.8");
1997        assert_eq!(x.trunc_digits(0).to_string(), "-24536");
1998        assert_eq!(x.trunc_digits(-1).to_string(), "-24530");
1999        assert_eq!(x.trunc_digits(-2).to_string(), "-24500");
2000        assert_eq!(x.trunc_digits(-3).to_string(), "-24000");
2001        assert_eq!(x.trunc_digits(-4).to_string(), "-20000");
2002        assert_eq!(x.trunc_digits(-5).to_string(), "0");
2003        assert_eq!(x.trunc_digits(-50).to_string(), "0");
2004    }
2005
2006    #[test]
2007    fn sign() {
2008        assert_eq!(f(-0.1).sign(), Fixed::<1, 0>::try_from(-1).unwrap());
2009        assert_eq!(f(0.0).sign(), Fixed::<1, 0>::try_from(0).unwrap());
2010        assert_eq!(f(0.5).sign(), Fixed::<1, 0>::try_from(1).unwrap());
2011    }
2012
2013    #[test]
2014    fn sqrt() {
2015        // A few selected values.
2016        assert_eq!(f(0.0).sqrt(), f(0.0));
2017        assert_eq!(f(1.0).sqrt(), f(1.0));
2018        assert_eq!(f(2.0).sqrt(), f(1.41));
2019        assert_eq!(f(3.0).sqrt(), f(1.73));
2020        assert_eq!(f(4.0).sqrt(), f(2.0));
2021        assert_eq!(f(-1.0).checked_sqrt(), None);
2022
2023        // General case.
2024        for a in 0..=999 {
2025            let af: Fixed<10, 2> = Fixed(a);
2026            assert_eq!(af.sqrt(), Fixed::<10, 2>((a * 100).isqrt()));
2027        }
2028    }
2029
2030    #[test]
2031    fn nullable() {
2032        /// Adds `a` and `b` and returns the sum.  Return `None` if `a` or `b`
2033        /// is `None` or if their sum is out of range.
2034        fn nullable_checked_add_generic<
2035            const PA: usize,
2036            const SA: usize,
2037            const PB: usize,
2038            const SB: usize,
2039            const PC: usize,
2040            const SC: usize,
2041        >(
2042            a: Option<Fixed<PA, SA>>,
2043            b: Option<Fixed<PB, SB>>,
2044        ) -> Option<Fixed<PC, SC>> {
2045            a.zip(b).and_then(|(a, b)| a.checked_add_generic(b))
2046        }
2047
2048        let a: Option<Fixed<10, 2>> = Some("1.23".parse().unwrap());
2049        let b: Option<Fixed<5, 4>> = Some("4.5678".parse().unwrap());
2050        let c: Option<Fixed<10, 4>> = nullable_checked_add_generic(a, b);
2051        assert_eq!(c, Some("5.7978".parse().unwrap()));
2052    }
2053
2054    #[test]
2055    fn to_integer() {
2056        for x in -9999..=9999 {
2057            let f = Fixed::<4, 1>(x);
2058            assert_eq!(i128::from(f), x / 10);
2059            assert_eq!(i64::try_from(f).unwrap(), (x / 10) as i64);
2060            assert_eq!(i32::try_from(f).unwrap(), (x / 10) as i32);
2061            assert_eq!(i16::try_from(f).unwrap(), (x / 10) as i16);
2062            assert_eq!(
2063                i8::try_from(f).ok(),
2064                (-1289..=1279).contains(&x).then_some((x / 10) as i8)
2065            );
2066            assert_eq!(
2067                u128::try_from(f).ok(),
2068                (x > -10).then_some((x / 10) as u128)
2069            );
2070            assert_eq!(u64::try_from(f).ok(), (x > -10).then_some((x / 10) as u64));
2071            assert_eq!(u32::try_from(f).ok(), (x > -10).then_some((x / 10) as u32));
2072            assert_eq!(u16::try_from(f).ok(), (x > -10).then_some((x / 10) as u16));
2073            assert_eq!(
2074                u8::try_from(f).ok(),
2075                (-9..=2559).contains(&x).then_some((x / 10) as u8)
2076            );
2077        }
2078    }
2079
2080    #[test]
2081    fn compare_against_fixed() {
2082        fn check_comparisons<const PA: usize, const SA: usize, const PB: usize, const SB: usize>(
2083            fx: Fixed<PA, SA>,
2084            fy: Fixed<PB, SB>,
2085            x: i128,
2086            y: i128,
2087        ) {
2088            assert_eq!(fx == fy, x == y);
2089            assert_eq!(fx != fy, x != y);
2090            assert_eq!(fx > fy, x > y);
2091            assert_eq!(fx >= fy, x >= y);
2092            assert_eq!(fx < fy, x < y);
2093            assert_eq!(fx <= fy, x <= y);
2094        }
2095
2096        for x in -999..=999 {
2097            let fx = Fixed::<3, 1>(x);
2098            for y in -999..=999 {
2099                check_comparisons(fx, Fixed::<3, 0>(y), x, y * 10);
2100                check_comparisons(fx, Fixed::<3, 1>(y), x, y);
2101                check_comparisons(fx, Fixed::<3, 2>(y), x * 10, y);
2102            }
2103        }
2104    }
2105
2106    #[test]
2107    fn compare_against_integers() {
2108        for x in -999..=999 {
2109            let f = Fixed::<3, 1>(x);
2110            for y in -100..=100 {
2111                let expect = x == y * 10;
2112                assert_eq!(f == y as i8, expect);
2113                assert_eq!(f == y as i16, expect);
2114                assert_eq!(f == y as i32, expect);
2115                assert_eq!(f == y as i64, expect);
2116                assert_eq!(f == y, expect);
2117                assert_eq!(f == y as isize, expect);
2118                if y >= 0 {
2119                    assert_eq!(f == y as u8, expect);
2120                    assert_eq!(f == y as u16, expect);
2121                    assert_eq!(f == y as u32, expect);
2122                    assert_eq!(f == y as u64, expect);
2123                    assert_eq!(f == y as u128, expect);
2124                    assert_eq!(f == y as usize, expect);
2125                }
2126            }
2127        }
2128    }
2129
2130    #[test]
2131    fn unsigned_encoding() {
2132        type F = Fixed<3, 1>;
2133        for x in -999..=999 {
2134            let f = Fixed::<3, 1>(x);
2135            assert_eq!(F::from_unsigned_encoding(f.to_unsigned_encoding()), Some(f));
2136        }
2137        assert_eq!(F::MIN.to_unsigned_encoding(), 0);
2138        assert_eq!(F::ZERO.to_unsigned_encoding(), 999);
2139        assert_eq!(F::MAX.to_unsigned_encoding(), 999 * 2);
2140        assert_eq!(F::from_unsigned_encoding(0), Some(F::MIN));
2141        assert_eq!(F::from_unsigned_encoding(999), Some(F::ZERO));
2142        assert_eq!(F::from_unsigned_encoding(999 * 2), Some(F::MAX));
2143        assert_eq!(F::from_unsigned_encoding(999 * 2 + 1), None);
2144    }
2145
2146    #[test]
2147    fn new() {
2148        type F1 = Fixed<11, 1>;
2149        assert_eq!(F1::new(435, -8), None);
2150        assert_eq!(F1::new(435, -7).unwrap().to_string(), "4350000000");
2151        assert_eq!(F1::new(435, -6).unwrap().to_string(), "435000000");
2152        assert_eq!(F1::new(435, -5).unwrap().to_string(), "43500000");
2153        assert_eq!(F1::new(435, -4).unwrap().to_string(), "4350000");
2154        assert_eq!(F1::new(435, -3).unwrap().to_string(), "435000");
2155        assert_eq!(F1::new(435, -2).unwrap().to_string(), "43500");
2156        assert_eq!(F1::new(435, -1).unwrap().to_string(), "4350");
2157        assert_eq!(F1::new(435, 0).unwrap().to_string(), "435");
2158        assert_eq!(F1::new(435, 1).unwrap().to_string(), "43.5");
2159        assert_eq!(F1::new(435, 2).unwrap().to_string(), "4.3");
2160        assert_eq!(F1::new(435, 3).unwrap().to_string(), "0.4");
2161        assert_eq!(F1::new(435, 4).unwrap().to_string(), "0");
2162
2163        type F2 = Fixed<11, 2>;
2164        assert_eq!(F2::new(435, -7), None);
2165        assert_eq!(F2::new(435, -6).unwrap().to_string(), "435000000");
2166        assert_eq!(F2::new(435, -5).unwrap().to_string(), "43500000");
2167        assert_eq!(F2::new(435, -4).unwrap().to_string(), "4350000");
2168        assert_eq!(F2::new(435, -3).unwrap().to_string(), "435000");
2169        assert_eq!(F2::new(435, -2).unwrap().to_string(), "43500");
2170        assert_eq!(F2::new(435, -1).unwrap().to_string(), "4350");
2171        assert_eq!(F2::new(435, 0).unwrap().to_string(), "435");
2172        assert_eq!(F2::new(435, 1).unwrap().to_string(), "43.5");
2173        assert_eq!(F2::new(435, 2).unwrap().to_string(), "4.35");
2174        assert_eq!(F2::new(435, 3).unwrap().to_string(), "0.43");
2175        assert_eq!(F2::new(435, 4).unwrap().to_string(), "0.04");
2176        assert_eq!(F2::new(435, 5).unwrap().to_string(), "0");
2177    }
2178
2179    #[test]
2180    fn new_round_even() {
2181        type F1 = Fixed<11, 1>;
2182        assert_eq!(F1::new_round_even(435, -8), None);
2183        assert_eq!(
2184            F1::new_round_even(435, -7).unwrap().to_string(),
2185            "4350000000"
2186        );
2187        assert_eq!(
2188            F1::new_round_even(435, -6).unwrap().to_string(),
2189            "435000000"
2190        );
2191        assert_eq!(F1::new_round_even(435, -5).unwrap().to_string(), "43500000");
2192        assert_eq!(F1::new_round_even(435, -4).unwrap().to_string(), "4350000");
2193        assert_eq!(F1::new_round_even(435, -3).unwrap().to_string(), "435000");
2194        assert_eq!(F1::new_round_even(435, -2).unwrap().to_string(), "43500");
2195        assert_eq!(F1::new_round_even(435, -1).unwrap().to_string(), "4350");
2196        assert_eq!(F1::new_round_even(435, 0).unwrap().to_string(), "435");
2197        assert_eq!(F1::new_round_even(435, 1).unwrap().to_string(), "43.5");
2198        assert_eq!(F1::new_round_even(435, 2).unwrap().to_string(), "4.4");
2199        assert_eq!(F1::new_round_even(435, 3).unwrap().to_string(), "0.4");
2200        assert_eq!(F1::new_round_even(435, 4).unwrap().to_string(), "0");
2201
2202        type F2 = Fixed<11, 2>;
2203        assert_eq!(F2::new_round_even(435, -7), None);
2204        assert_eq!(
2205            F2::new_round_even(435, -6).unwrap().to_string(),
2206            "435000000"
2207        );
2208        assert_eq!(F2::new_round_even(435, -5).unwrap().to_string(), "43500000");
2209        assert_eq!(F2::new_round_even(435, -4).unwrap().to_string(), "4350000");
2210        assert_eq!(F2::new_round_even(435, -3).unwrap().to_string(), "435000");
2211        assert_eq!(F2::new_round_even(435, -2).unwrap().to_string(), "43500");
2212        assert_eq!(F2::new_round_even(435, -1).unwrap().to_string(), "4350");
2213        assert_eq!(F2::new_round_even(435, 0).unwrap().to_string(), "435");
2214        assert_eq!(F2::new_round_even(435, 1).unwrap().to_string(), "43.5");
2215        assert_eq!(F2::new_round_even(435, 2).unwrap().to_string(), "4.35");
2216        assert_eq!(F2::new_round_even(435, 3).unwrap().to_string(), "0.44");
2217        assert_eq!(F2::new_round_even(435, 4).unwrap().to_string(), "0.04");
2218        assert_eq!(F2::new_round_even(435, 5).unwrap().to_string(), "0");
2219    }
2220}