fixed/
arith.rs

1// Copyright © 2018–2025 Trevor Spiteri
2
3// This library is free software: you can redistribute it and/or
4// modify it under the terms of either
5//
6//   * the Apache License, Version 2.0 or
7//   * the MIT License
8//
9// at your option.
10//
11// You should have recieved copies of the Apache License and the MIT
12// License along with the library. If not, see
13// <https://www.apache.org/licenses/LICENSE-2.0> and
14// <https://opensource.org/licenses/MIT>.
15
16use crate::traits::ToFixed;
17use crate::types::extra::{LeEqU8, LeEqU16, LeEqU32, LeEqU64, LeEqU128};
18use crate::{
19    FixedI8, FixedI16, FixedI32, FixedI64, FixedI128, FixedU8, FixedU16, FixedU32, FixedU64,
20    FixedU128,
21};
22use core::hint;
23use core::iter::{Product, Sum};
24use core::num::NonZero;
25use core::ops::{
26    Add, AddAssign, BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Div, DivAssign,
27    Mul, MulAssign, Neg, Not, Rem, RemAssign, Shl, ShlAssign, Shr, ShrAssign, Sub, SubAssign,
28};
29
30macro_rules! refs {
31    (impl $Imp:ident for $Fixed:ident$(($LeEqU:ident))* { $method:ident }) => {
32        impl<Frac $(: $LeEqU)*> $Imp<$Fixed<Frac>> for &$Fixed<Frac> {
33            type Output = $Fixed<Frac>;
34            #[inline]
35            fn $method(self, rhs: $Fixed<Frac>) -> $Fixed<Frac> {
36                (*self).$method(rhs)
37            }
38        }
39
40        impl<Frac $(: $LeEqU)*> $Imp<&$Fixed<Frac>> for $Fixed<Frac> {
41            type Output = $Fixed<Frac>;
42            #[inline]
43            fn $method(self, rhs: &$Fixed<Frac>) -> $Fixed<Frac> {
44                self.$method(*rhs)
45            }
46        }
47
48        impl<Frac $(: $LeEqU)*> $Imp<&$Fixed<Frac>> for &$Fixed<Frac> {
49            type Output = $Fixed<Frac>;
50            #[inline]
51            fn $method(self, rhs: &$Fixed<Frac>) -> $Fixed<Frac> {
52                (*self).$method(*rhs)
53            }
54        }
55    };
56
57    (impl $Imp:ident<$Inner:ty> for $Fixed:ident$(($LeEqU:ident))* { $method:ident }) => {
58        impl<Frac $(: $LeEqU)*> $Imp<$Inner> for &$Fixed<Frac> {
59            type Output = $Fixed<Frac>;
60            #[inline]
61            fn $method(self, rhs: $Inner) -> $Fixed<Frac> {
62                (*self).$method(rhs)
63            }
64        }
65
66        impl<Frac $(: $LeEqU)*> $Imp<&$Inner> for $Fixed<Frac> {
67            type Output = $Fixed<Frac>;
68            #[inline]
69            fn $method(self, rhs: &$Inner) -> $Fixed<Frac> {
70                self.$method(*rhs)
71            }
72        }
73
74        impl<Frac $(: $LeEqU)*> $Imp<&$Inner> for &$Fixed<Frac> {
75            type Output = $Fixed<Frac>;
76            #[inline]
77            fn $method(self, rhs: &$Inner) -> $Fixed<Frac> {
78                (*self).$method(*rhs)
79            }
80        }
81    };
82}
83
84macro_rules! refs_assign {
85    (impl $Imp:ident for $Fixed:ident$(($LeEqU:ident))* { $method:ident }) => {
86        impl<Frac $(: $LeEqU)*> $Imp<&$Fixed<Frac>> for $Fixed<Frac> {
87            #[inline]
88            fn $method(&mut self, rhs: &$Fixed<Frac>) {
89                self.$method(*rhs);
90            }
91        }
92    };
93
94    (impl $Imp:ident<$Inner:ty> for $Fixed:ident$(($LeEqU:ident))* { $method:ident }) => {
95        impl<Frac $(: $LeEqU)*> $Imp<&$Inner> for $Fixed<Frac> {
96            #[inline]
97            fn $method(&mut self, rhs: &$Inner) {
98                self.$method(*rhs);
99            }
100        }
101    };
102}
103
104macro_rules! pass {
105    (impl $Imp:ident for $Fixed:ident { $method:ident }) => {
106        impl<Frac> $Imp<$Fixed<Frac>> for $Fixed<Frac> {
107            type Output = $Fixed<Frac>;
108            #[inline]
109            fn $method(self, rhs: $Fixed<Frac>) -> $Fixed<Frac> {
110                Self::from_bits(self.to_bits().$method(rhs.to_bits()))
111            }
112        }
113
114        refs! { impl $Imp for $Fixed { $method } }
115    };
116}
117
118macro_rules! pass_assign {
119    (impl $Imp:ident for $Fixed:ident { $method:ident }) => {
120        impl<Frac> $Imp<$Fixed<Frac>> for $Fixed<Frac> {
121            #[inline]
122            fn $method(&mut self, rhs: $Fixed<Frac>) {
123                self.bits.$method(rhs.to_bits())
124            }
125        }
126
127        refs_assign! { impl $Imp for $Fixed { $method } }
128    };
129}
130
131macro_rules! pass_one {
132    (impl $Imp:ident for $Fixed:ident { $method:ident }) => {
133        impl<Frac> $Imp for $Fixed<Frac> {
134            type Output = $Fixed<Frac>;
135            #[inline]
136            fn $method(self) -> $Fixed<Frac> {
137                Self::from_bits(self.to_bits().$method())
138            }
139        }
140
141        impl<Frac> $Imp for &$Fixed<Frac> {
142            type Output = $Fixed<Frac>;
143            #[inline]
144            fn $method(self) -> $Fixed<Frac> {
145                (*self).$method()
146            }
147        }
148    };
149}
150
151macro_rules! shift {
152    (impl $Imp:ident < $Rhs:ty > for $Fixed:ident { $method:ident }) => {
153        impl<Frac> $Imp<$Rhs> for $Fixed<Frac> {
154            type Output = $Fixed<Frac>;
155            #[inline]
156            fn $method(self, rhs: $Rhs) -> $Fixed<Frac> {
157                $Fixed::from_bits(self.to_bits().$method(rhs))
158            }
159        }
160
161        impl<Frac> $Imp<$Rhs> for &$Fixed<Frac> {
162            type Output = $Fixed<Frac>;
163            #[inline]
164            fn $method(self, rhs: $Rhs) -> $Fixed<Frac> {
165                (*self).$method(rhs)
166            }
167        }
168
169        impl<Frac> $Imp<&$Rhs> for $Fixed<Frac> {
170            type Output = $Fixed<Frac>;
171            #[inline]
172            fn $method(self, rhs: &$Rhs) -> $Fixed<Frac> {
173                self.$method(*rhs)
174            }
175        }
176
177        impl<Frac> $Imp<&$Rhs> for &$Fixed<Frac> {
178            type Output = $Fixed<Frac>;
179            #[inline]
180            fn $method(self, rhs: &$Rhs) -> $Fixed<Frac> {
181                (*self).$method(*rhs)
182            }
183        }
184    };
185}
186
187macro_rules! shift_assign {
188    (impl $Imp:ident < $Rhs:ty > for $Fixed:ident { $method:ident }) => {
189        impl<Frac> $Imp<$Rhs> for $Fixed<Frac> {
190            #[inline]
191            fn $method(&mut self, rhs: $Rhs) {
192                self.bits.$method(rhs)
193            }
194        }
195
196        impl<Frac> $Imp<&$Rhs> for $Fixed<Frac> {
197            #[inline]
198            fn $method(&mut self, rhs: &$Rhs) {
199                self.$method(*rhs)
200            }
201        }
202    };
203}
204
205macro_rules! shift_all {
206    (
207        impl {$Imp:ident, $ImpAssign:ident}<{$($Rhs:ty),*}> for $Fixed:ident
208        { $method:ident, $method_assign:ident }
209    ) => { $(
210        shift! { impl $Imp<$Rhs> for $Fixed { $method } }
211        shift_assign! { impl $ImpAssign<$Rhs> for $Fixed { $method_assign } }
212    )* };
213}
214
215macro_rules! fixed_arith {
216    (
217        $Fixed:ident($Inner:ident, $LeEqU:ident, $bits_count:expr),
218        $Signedness:ident
219    ) => {
220        if_signed! {
221            $Signedness;
222            pass_one! { impl Neg for $Fixed { neg } }
223        }
224
225        pass! { impl Add for $Fixed { add } }
226        pass_assign! { impl AddAssign for $Fixed { add_assign } }
227        pass! { impl Sub for $Fixed { sub } }
228        pass_assign! { impl SubAssign for $Fixed { sub_assign } }
229
230        impl<Frac: $LeEqU> Mul<$Fixed<Frac>> for $Fixed<Frac> {
231            type Output = $Fixed<Frac>;
232            #[inline]
233            fn mul(self, rhs: $Fixed<Frac>) -> $Fixed<Frac> {
234                let (ans, overflow) =
235                    $Inner::overflowing_mul(self.to_bits(), rhs.to_bits(), Frac::U32);
236                debug_assert!(!overflow, "overflow");
237                Self::from_bits(ans)
238            }
239        }
240
241        refs! { impl Mul for $Fixed($LeEqU) { mul } }
242
243        impl<Frac, RhsFrac: $LeEqU> MulAssign<$Fixed<RhsFrac>> for $Fixed<Frac> {
244            #[inline]
245            fn mul_assign(&mut self, rhs: $Fixed<RhsFrac>) {
246                let (ans, overflow) =
247                    $Inner::overflowing_mul(self.to_bits(), rhs.to_bits(), RhsFrac::U32);
248                debug_assert!(!overflow, "overflow");
249                *self = Self::from_bits(ans);
250            }
251        }
252
253        impl<Frac, RhsFrac: $LeEqU> MulAssign<&$Fixed<RhsFrac>> for $Fixed<Frac> {
254            #[inline]
255            fn mul_assign(&mut self, rhs: &$Fixed<RhsFrac>) {
256                let (ans, overflow) =
257                    $Inner::overflowing_mul(self.to_bits(), rhs.to_bits(), RhsFrac::U32);
258                debug_assert!(!overflow, "overflow");
259                *self = Self::from_bits(ans);
260            }
261        }
262
263        impl<Frac: $LeEqU> Div<$Fixed<Frac>> for $Fixed<Frac> {
264            type Output = $Fixed<Frac>;
265            #[inline]
266            fn div(self, rhs: $Fixed<Frac>) -> $Fixed<Frac> {
267                let (ans, overflow) =
268                    $Inner::overflowing_div(self.to_bits(), rhs.to_bits(), Frac::U32);
269                debug_assert!(!overflow, "overflow");
270                Self::from_bits(ans)
271            }
272        }
273
274        refs! { impl Div for $Fixed($LeEqU) { div } }
275
276        impl<Frac: $LeEqU> DivAssign<$Fixed<Frac>> for $Fixed<Frac> {
277            #[inline]
278            fn div_assign(&mut self, rhs: $Fixed<Frac>) {
279                *self = (*self).div(rhs)
280            }
281        }
282
283        refs_assign! { impl DivAssign for $Fixed($LeEqU) { div_assign } }
284
285        // do not pass! { Rem }, as I::MIN % I::from(-1) should return 0, not panic
286        impl<Frac> Rem<$Fixed<Frac>> for $Fixed<Frac> {
287            type Output = $Fixed<Frac>;
288            #[inline]
289            fn rem(self, rhs: $Fixed<Frac>) -> $Fixed<Frac> {
290                self.checked_rem(rhs).expect("division by zero")
291            }
292        }
293
294        refs! { impl Rem for $Fixed { rem } }
295
296        impl<Frac> RemAssign<$Fixed<Frac>> for $Fixed<Frac> {
297            #[inline]
298            fn rem_assign(&mut self, rhs: $Fixed<Frac>) {
299                *self = (*self).rem(rhs)
300            }
301        }
302
303        refs_assign! { impl RemAssign for $Fixed { rem_assign } }
304
305        pass_one! { impl Not for $Fixed { not } }
306        pass! { impl BitAnd for $Fixed { bitand } }
307        pass_assign! { impl BitAndAssign for $Fixed { bitand_assign } }
308        pass! { impl BitOr for $Fixed { bitor } }
309        pass_assign! { impl BitOrAssign for $Fixed { bitor_assign } }
310        pass! { impl BitXor for $Fixed { bitxor } }
311        pass_assign! { impl BitXorAssign for $Fixed { bitxor_assign } }
312
313        impl<Frac> Mul<$Inner> for $Fixed<Frac> {
314            type Output = $Fixed<Frac>;
315            #[inline]
316            fn mul(self, rhs: $Inner) -> $Fixed<Frac> {
317                Self::from_bits(self.to_bits().mul(rhs))
318            }
319        }
320
321        refs! { impl Mul<$Inner> for $Fixed($LeEqU) { mul } }
322
323        impl<Frac: $LeEqU> MulAssign<$Inner> for $Fixed<Frac> {
324            #[inline]
325            fn mul_assign(&mut self, rhs: $Inner) {
326                *self = (*self).mul(rhs);
327            }
328        }
329
330        refs_assign! { impl MulAssign<$Inner> for $Fixed($LeEqU) { mul_assign } }
331
332        impl<Frac: $LeEqU> Mul<$Fixed<Frac>> for $Inner {
333            type Output = $Fixed<Frac>;
334            #[inline]
335            fn mul(self, rhs: $Fixed<Frac>) -> $Fixed<Frac> {
336                rhs.mul(self)
337            }
338        }
339
340        impl<Frac: $LeEqU> Mul<&$Fixed<Frac>> for $Inner {
341            type Output = $Fixed<Frac>;
342            #[inline]
343            fn mul(self, rhs: &$Fixed<Frac>) -> $Fixed<Frac> {
344                (*rhs).mul(self)
345            }
346        }
347
348        impl<Frac: $LeEqU> Mul<$Fixed<Frac>> for &$Inner {
349            type Output = $Fixed<Frac>;
350            #[inline]
351            fn mul(self, rhs: $Fixed<Frac>) -> $Fixed<Frac> {
352                rhs.mul(*self)
353            }
354        }
355
356        impl<Frac: $LeEqU> Mul<&$Fixed<Frac>> for &$Inner {
357            type Output = $Fixed<Frac>;
358            #[inline]
359            fn mul(self, rhs: &$Fixed<Frac>) -> $Fixed<Frac> {
360                (*rhs).mul(*self)
361            }
362        }
363
364        impl<Frac> Div<$Inner> for $Fixed<Frac> {
365            type Output = $Fixed<Frac>;
366            #[inline]
367            fn div(self, rhs: $Inner) -> $Fixed<Frac> {
368                Self::from_bits(self.to_bits().div(rhs))
369            }
370        }
371
372        refs! { impl Div<$Inner> for $Fixed($LeEqU) { div } }
373
374        impl<Frac: $LeEqU> DivAssign<$Inner> for $Fixed<Frac> {
375            #[inline]
376            fn div_assign(&mut self, rhs: $Inner) {
377                *self = (*self).div(rhs);
378            }
379        }
380
381        refs_assign! { impl DivAssign<$Inner> for $Fixed($LeEqU) { div_assign } }
382
383        impl<Frac: $LeEqU> Rem<$Inner> for $Fixed<Frac> {
384            type Output = $Fixed<Frac>;
385            #[inline]
386            fn rem(self, rhs: $Inner) -> $Fixed<Frac> {
387                self.checked_rem_int(rhs).expect("division by zero")
388            }
389        }
390
391        refs! { impl Rem<$Inner> for $Fixed($LeEqU) { rem } }
392
393        impl<Frac: $LeEqU> RemAssign<$Inner> for $Fixed<Frac> {
394            #[inline]
395            fn rem_assign(&mut self, rhs: $Inner) {
396                *self = (*self).rem(rhs);
397            }
398        }
399
400        refs_assign! { impl RemAssign<$Inner> for $Fixed($LeEqU) { rem_assign } }
401
402        shift_all! {
403            impl {Shl, ShlAssign}<{
404                i8, i16, i32, i64, i128, isize, u8, u16, u32, u64, u128, usize
405            }> for $Fixed {
406                shl, shl_assign
407            }
408        }
409        shift_all! {
410            impl {Shr, ShrAssign}<{
411                i8, i16, i32, i64, i128, isize, u8, u16, u32, u64, u128, usize
412            }> for $Fixed {
413                shr, shr_assign
414            }
415        }
416
417        impl<Frac> Sum<$Fixed<Frac>> for $Fixed<Frac> {
418            fn sum<I>(iter: I) -> $Fixed<Frac>
419            where
420                I: Iterator<Item = $Fixed<Frac>>,
421            {
422                iter.fold(Self::ZERO, Add::add)
423            }
424        }
425
426        impl<'a, Frac: 'a> Sum<&'a $Fixed<Frac>> for $Fixed<Frac> {
427            fn sum<I>(iter: I) -> $Fixed<Frac>
428            where
429                I: Iterator<Item = &'a $Fixed<Frac>>,
430            {
431                iter.fold(Self::ZERO, Add::add)
432            }
433        }
434
435        impl<Frac: $LeEqU> Product<$Fixed<Frac>> for $Fixed<Frac> {
436            fn product<I>(mut iter: I) -> $Fixed<Frac>
437            where
438                I: Iterator<Item = $Fixed<Frac>>,
439            {
440                match iter.next() {
441                    None => 1.to_fixed(),
442                    Some(first) => iter.fold(first, Mul::mul),
443                }
444            }
445        }
446
447        impl<'a, Frac: 'a + $LeEqU> Product<&'a $Fixed<Frac>> for $Fixed<Frac> {
448            fn product<I>(mut iter: I) -> $Fixed<Frac>
449            where
450                I: Iterator<Item = &'a $Fixed<Frac>>,
451            {
452                match iter.next() {
453                    None => 1.to_fixed(),
454                    Some(first) => iter.fold(*first, Mul::mul),
455                }
456            }
457        }
458
459        if_unsigned! {
460            $Signedness;
461
462            impl<Frac> Div<NonZero<$Inner>> for $Fixed<Frac> {
463                type Output = $Fixed<Frac>;
464                #[inline]
465                fn div(self, rhs: NonZero<$Inner>) -> $Fixed<Frac> {
466                    Self::from_bits(self.to_bits() / rhs)
467                }
468            }
469
470            refs! { impl Div<NonZero<$Inner>> for $Fixed { div } }
471
472            impl <Frac> DivAssign<NonZero<$Inner>> for $Fixed<Frac> {
473                #[inline]
474                fn div_assign(&mut self, rhs: NonZero<$Inner>) {
475                    *self = (*self).div(rhs)
476                }
477            }
478
479            refs_assign! { impl DivAssign<NonZero<$Inner>> for $Fixed { div_assign } }
480
481            impl<Frac: $LeEqU> Rem<NonZero<$Inner>> for $Fixed<Frac> {
482                type Output = $Fixed<Frac>;
483                #[inline]
484                fn rem(self, rhs: NonZero<$Inner>) -> $Fixed<Frac> {
485                    // Hack to silence overflow operation error if we shift
486                    // by Self::FRAC_NBITS directly.
487                    let frac_nbits = Self::FRAC_NBITS;
488                    let rhs = rhs.get();
489                    if frac_nbits == <$Inner>::BITS {
490                        // rhs > self, so the remainder is self
491                        return self;
492                    }
493                    let rhs_fixed_bits = rhs << frac_nbits;
494                    if (rhs_fixed_bits >> frac_nbits) != rhs {
495                        // rhs > self, so the remainder is self
496                        return self;
497                    }
498                    // SAFETY: rhs_fixed_bits must have some significant bits since
499                    // rhs_fixed_bits >> frac_nbits is equal to a non-zero value.
500                    debug_assert_ne!(rhs_fixed_bits, 0);
501                    let n = unsafe { NonZero::<$Inner>::new_unchecked(rhs_fixed_bits) };
502                    Self::from_bits(self.to_bits() % n)
503                }
504            }
505        }
506
507        if_signed! {
508            $Signedness;
509
510            impl<Frac: $LeEqU> Rem<NonZero<$Inner>> for $Fixed<Frac> {
511                type Output = $Fixed<Frac>;
512                #[inline]
513                fn rem(self, rhs: NonZero<$Inner>) -> $Fixed<Frac> {
514                    // Hack to silence overflow operation error if we shift
515                    // by Self::FRAC_NBITS directly.
516                    let frac_nbits = Self::FRAC_NBITS;
517                    let rhs = rhs.get();
518                    let mut overflow = false;
519                    let rhs_fixed_bits = if frac_nbits == <$Inner>::BITS {
520                        overflow = true;
521                        0
522                    } else {
523                        rhs << frac_nbits
524                    };
525                    if overflow || (rhs_fixed_bits >> frac_nbits) != rhs {
526                        // Either
527                        //   * |rhs| > |self|, and so remainder is self, or
528                        //   * self is signed min with at least one integer bit,
529                        //     and the value of rhs is -self, so remainder is 0.
530                        return if self == Self::MIN
531                            && (Self::INT_NBITS > 0 && rhs == 1 << (Self::INT_NBITS - 1))
532                        {
533                            Self::ZERO
534                        } else {
535                            self
536                        };
537                    }
538                    if rhs_fixed_bits == -1 {
539                        return Self::ZERO;
540                    }
541                    // SAFETY: rhs_fixed_bits cannot be -1, and cannot be zero because
542                    // rhs_fixed_bits >> frac_nbits is equal to a non-zero value,
543                    // so the remainder operation cannot fail.
544                    match self.to_bits().checked_rem(rhs_fixed_bits) {
545                        Some(rem) => Self::from_bits(rem),
546                        None => unsafe { hint::unreachable_unchecked() },
547                    }
548                }
549            }
550        }
551
552        refs! { impl Rem<NonZero<$Inner>> for $Fixed($LeEqU) { rem } }
553
554        impl<Frac: $LeEqU> RemAssign<NonZero<$Inner>> for $Fixed<Frac> {
555            #[inline]
556            fn rem_assign(&mut self, rhs: NonZero<$Inner>) {
557                *self = (*self).rem(rhs)
558            }
559        }
560
561        refs_assign! { impl RemAssign<NonZero<$Inner>> for $Fixed($LeEqU) { rem_assign } }
562    };
563}
564
565fixed_arith! { FixedU8(u8, LeEqU8, 8), Unsigned }
566fixed_arith! { FixedU16(u16, LeEqU16, 16), Unsigned }
567fixed_arith! { FixedU32(u32, LeEqU32, 32), Unsigned }
568fixed_arith! { FixedU64(u64, LeEqU64, 64), Unsigned }
569fixed_arith! { FixedU128(u128, LeEqU128, 128), Unsigned }
570fixed_arith! { FixedI8(i8, LeEqU8, 8), Signed }
571fixed_arith! { FixedI16(i16, LeEqU16, 16), Signed }
572fixed_arith! { FixedI32(i32, LeEqU32, 32), Signed }
573fixed_arith! { FixedI64(i64, LeEqU64, 64), Signed }
574fixed_arith! { FixedI128(i128, LeEqU128, 128), Signed }
575
576macro_rules! mul_div_widen {
577    ($Single:ident, $Double:ty, $Signedness:ident, $Unsigned:ty) => {
578        pub mod $Single {
579            // 0 <= frac_nbits <= NBITS
580            #[inline]
581            pub const fn overflowing_mul(
582                lhs: $Single,
583                rhs: $Single,
584                frac_nbits: u32,
585            ) -> ($Single, bool) {
586                const NBITS: u32 = <$Single>::BITS;
587                let int_nbits: u32 = NBITS - frac_nbits;
588                let lhs2 = lhs as $Double;
589                let rhs2 = (rhs as $Double) << int_nbits;
590                let (prod2, overflow) = lhs2.overflowing_mul(rhs2);
591                ((prod2 >> NBITS) as $Single, overflow)
592            }
593
594            // -NBITS <= frac_nbits <= 2 * NBITS
595            #[inline]
596            pub const fn overflowing_mul_add(
597                lhs: $Single,
598                mul: $Single,
599                add: $Single,
600                mut frac_nbits: i32,
601            ) -> ($Single, bool) {
602                const NBITS: i32 = <$Single>::BITS as i32;
603                let lhs2 = lhs as $Double;
604                let mul2 = mul as $Double;
605                let prod2 = lhs2 * mul2;
606                let (prod2, overflow2) = if frac_nbits < 0 {
607                    frac_nbits += NBITS;
608                    debug_assert!(frac_nbits >= 0);
609                    prod2.overflowing_mul(<$Unsigned>::MAX as $Double + 1)
610                } else if frac_nbits > NBITS {
611                    frac_nbits -= NBITS;
612                    debug_assert!(frac_nbits <= NBITS);
613                    (prod2 >> NBITS, false)
614                } else {
615                    (prod2, false)
616                };
617                let lo = (prod2 >> frac_nbits) as $Unsigned;
618                let hi = (prod2 >> frac_nbits >> NBITS) as $Single;
619                if_signed_unsigned!(
620                    $Signedness,
621                    {
622                        let (uns, carry) = lo.overflowing_add(add as $Unsigned);
623                        let ans = uns as $Single;
624                        let expected_hi = if (ans.is_negative() != add.is_negative()) == carry {
625                            0
626                        } else {
627                            -1
628                        };
629                        (ans, overflow2 || hi != expected_hi)
630                    },
631                    {
632                        let (ans, overflow) = lo.overflowing_add(add);
633                        (ans, overflow2 || overflow || hi != 0)
634                    },
635                )
636            }
637
638            // 0 <= frac_nbits <= NBITS
639            #[inline]
640            pub const fn overflowing_div(
641                lhs: $Single,
642                rhs: $Single,
643                frac_nbits: u32,
644            ) -> ($Single, bool) {
645                const NBITS: u32 = <$Single>::BITS;
646                let lhs2 = (lhs as $Double) << frac_nbits;
647                let rhs2 = (rhs as $Double);
648                // Overflow at this stage can only occur for signed when
649                // frac_nbits == NBITS, lhs == MIN, and rhs == -1.
650                // In that case, wrapped answer is $Double::MIN as $Single == 0
651                let (quot2, false) = lhs2.overflowing_div(rhs2) else {
652                    return (0, true);
653                };
654                let quot = quot2 as $Single;
655                let overflow = if_signed_unsigned!(
656                    $Signedness,
657                    quot2 >> NBITS != if quot < 0 { -1 } else { 0 },
658                    quot2 >> NBITS != 0
659                );
660                (quot, overflow)
661            }
662        }
663    };
664}
665
666mul_div_widen! { u8, u16, Unsigned, u8 }
667mul_div_widen! { u16, u32, Unsigned, u16 }
668mul_div_widen! { u32, u64, Unsigned, u32 }
669mul_div_widen! { u64, u128, Unsigned, u64 }
670mul_div_widen! { i8, i16, Signed, u8 }
671mul_div_widen! { i16, i32, Signed, u16 }
672mul_div_widen! { i32, i64, Signed, u32 }
673mul_div_widen! { i64, i128, Signed, u64 }
674
675pub mod u128 {
676    use crate::int256;
677    use crate::int256::U256;
678    use core::num::NonZeroU128;
679
680    // 0 <= frac_nbits <= NBITS
681    #[inline]
682    pub const fn overflowing_mul(lhs: u128, rhs: u128, frac_nbits: u32) -> (u128, bool) {
683        if frac_nbits == 0 {
684            lhs.overflowing_mul(rhs)
685        } else {
686            let prod = int256::wide_mul_u128(lhs, rhs);
687            int256::overflowing_shl_u256_into_u128(prod, frac_nbits)
688        }
689    }
690
691    // -NBITS <= frac_nbits <= 2 * NBITS
692    #[inline]
693    pub const fn overflowing_mul_add(
694        m1: u128,
695        m2: u128,
696        add: u128,
697        mut frac_nbits: i32,
698    ) -> (u128, bool) {
699        // l * r + a
700        let mut prod = int256::wide_mul_u128(m1, m2);
701
702        let mut overflow1 = false;
703        if frac_nbits < 0 {
704            frac_nbits += 128;
705            debug_assert!(frac_nbits >= 0);
706            overflow1 = prod.hi != 0;
707            prod.hi = prod.lo;
708            prod.lo = 0;
709        } else if frac_nbits > 128 {
710            frac_nbits -= 128;
711            debug_assert!(frac_nbits <= 128);
712            prod.lo = prod.hi;
713            prod.hi = 0;
714        }
715
716        let (shifted, overflow2) = int256::overflowing_shl_u256_into_u128(prod, frac_nbits as u32);
717        let (ans, overflow3) = shifted.overflowing_add(add);
718        (ans, overflow1 | overflow2 | overflow3)
719    }
720
721    // 0 <= frac_nbits <= NBITS
722    #[inline]
723    pub const fn overflowing_div(lhs: u128, rhs: u128, frac_nbits: u32) -> (u128, bool) {
724        if frac_nbits == 0 {
725            return lhs.overflowing_div(rhs);
726        }
727        let Some(rhs) = NonZeroU128::new(rhs) else {
728            panic!("division by zero");
729        };
730        overflowing_div_nz(lhs, rhs, frac_nbits)
731    }
732
733    // Neither rhs nor frac_nbits is zero.
734    const fn overflowing_div_nz(lhs: u128, rhs: NonZeroU128, frac_nbits: u32) -> (u128, bool) {
735        let lhs2 = if frac_nbits == 128 {
736            U256 { lo: 0, hi: lhs }
737        } else {
738            U256 {
739                lo: lhs << frac_nbits,
740                hi: lhs >> (128 - frac_nbits),
741            }
742        };
743        let (quot2, _) = int256::div_rem_u256_u128(lhs2, rhs);
744        let quot = quot2.lo;
745        let overflow = quot2.hi != 0;
746        (quot, overflow)
747    }
748}
749
750pub mod i128 {
751    use crate::int256;
752    use crate::int256::I256;
753    use core::num::NonZeroI128;
754
755    // 0 <= frac_nbits <= NBITS
756    #[inline]
757    pub const fn overflowing_mul(lhs: i128, rhs: i128, frac_nbits: u32) -> (i128, bool) {
758        if frac_nbits == 0 {
759            lhs.overflowing_mul(rhs)
760        } else {
761            let prod = int256::wide_mul_i128(lhs, rhs);
762            int256::overflowing_shl_i256_into_i128(prod, frac_nbits)
763        }
764    }
765
766    // -NBITS <= frac_nbits <= 2 * NBITS
767    #[inline]
768    pub const fn overflowing_mul_add(
769        m1: i128,
770        m2: i128,
771        add: i128,
772        mut frac_nbits: i32,
773    ) -> (i128, bool) {
774        // l * r + a
775        let mut prod = int256::wide_mul_i128(m1, m2);
776
777        let mut overflow1 = false;
778        if frac_nbits < 0 {
779            frac_nbits += 128;
780            debug_assert!(frac_nbits >= 0);
781            overflow1 = prod.hi != (prod.lo as i128) >> 127;
782            prod.hi = prod.lo as i128;
783            prod.lo = 0;
784        } else if frac_nbits > 128 {
785            frac_nbits -= 128;
786            debug_assert!(frac_nbits <= 128);
787            prod.lo = prod.hi as u128;
788            prod.hi >>= 127;
789        }
790
791        let shifted = int256::shl_i256_max_128(prod, frac_nbits as u32);
792        let (uns, carry) = shifted.lo.overflowing_add(add as u128);
793        let ans = uns as i128;
794        let mut expected_hi = ans >> 127;
795        if add < 0 {
796            expected_hi += 1;
797        }
798        if carry {
799            expected_hi -= 1;
800        }
801        (ans, overflow1 | (shifted.hi != expected_hi))
802    }
803
804    // 0 <= frac_nbits <= NBITS
805    #[inline]
806    pub const fn overflowing_div(lhs: i128, rhs: i128, frac_nbits: u32) -> (i128, bool) {
807        if frac_nbits == 0 {
808            return lhs.overflowing_div(rhs);
809        }
810        let Some(rhs) = NonZeroI128::new(rhs) else {
811            panic!("division by zero");
812        };
813        overflowing_div_nz(lhs, rhs, frac_nbits)
814    }
815
816    // Neither rhs nor frac_nbits is zero.
817    const fn overflowing_div_nz(lhs: i128, rhs: NonZeroI128, frac_nbits: u32) -> (i128, bool) {
818        let lhs2 = if frac_nbits == 128 {
819            // In this case, overflow is possible in the wide division.
820            // Then, the wrapped answer is I256::MIN as i128 == 0
821            if lhs == i128::MIN && rhs.get() == -1 {
822                return (0, true);
823            }
824            I256 { lo: 0, hi: lhs }
825        } else {
826            I256 {
827                lo: (lhs << frac_nbits) as u128,
828                hi: lhs >> (128 - frac_nbits),
829            }
830        };
831        let (quot2, _) = int256::div_rem_i256_i128_no_overflow(lhs2, rhs);
832        let quot = quot2.lo as i128;
833        let overflow = quot2.hi != quot >> 127;
834        (quot, overflow)
835    }
836}
837
838#[cfg(test)]
839mod tests {
840    use crate::*;
841
842    #[test]
843    fn fixed_u16() {
844        use crate::types::extra::U7 as Frac;
845        let frac = Frac::U32;
846        let a = 12;
847        let b = 5;
848        for &(a, b) in &[(a, b), (b, a)] {
849            let af = FixedU16::<Frac>::from_num(a);
850            let bf = FixedU16::<Frac>::from_num(b);
851            assert_eq!((af + bf).to_bits(), (a << frac) + (b << frac));
852            if a > b {
853                assert_eq!((af - bf).to_bits(), (a << frac) - (b << frac));
854            }
855            assert_eq!((af * bf).to_bits(), (a << frac) * b);
856            assert_eq!((af / bf).to_bits(), (a << frac) / b);
857            assert_eq!((af % bf).to_bits(), (a << frac) % (b << frac));
858            assert_eq!((af & bf).to_bits(), (a << frac) & (b << frac));
859            assert_eq!((af | bf).to_bits(), (a << frac) | (b << frac));
860            assert_eq!((af ^ bf).to_bits(), (a << frac) ^ (b << frac));
861            assert_eq!((!af).to_bits(), !(a << frac));
862            assert_eq!((af << 4u8).to_bits(), (a << frac) << 4);
863            assert_eq!((af >> 4i128).to_bits(), (a << frac) >> 4);
864            assert_eq!((af * b).to_bits(), (a << frac) * b);
865            assert_eq!((b * af).to_bits(), (a << frac) * b);
866            assert_eq!((af / b).to_bits(), (a << frac) / b);
867            assert_eq!((af % b).to_bits(), (a << frac) % (b << frac));
868        }
869    }
870
871    #[test]
872    fn fixed_i16() {
873        use crate::types::extra::U7 as Frac;
874        let frac = Frac::U32;
875        let a = 12;
876        let b = 5;
877        for &(a, b) in &[
878            (a, b),
879            (a, -b),
880            (-a, b),
881            (-a, -b),
882            (b, a),
883            (b, -a),
884            (-b, a),
885            (-b, -a),
886        ] {
887            let af = FixedI16::<Frac>::from_num(a);
888            let bf = FixedI16::<Frac>::from_num(b);
889            assert_eq!((af + bf).to_bits(), (a << frac) + (b << frac));
890            assert_eq!((af - bf).to_bits(), (a << frac) - (b << frac));
891            assert_eq!((af * bf).to_bits(), (a << frac) * b);
892            assert_eq!((af / bf).to_bits(), (a << frac) / b);
893            assert_eq!((af % bf).to_bits(), (a << frac) % (b << frac));
894            assert_eq!((af & bf).to_bits(), (a << frac) & (b << frac));
895            assert_eq!((af | bf).to_bits(), (a << frac) | (b << frac));
896            assert_eq!((af ^ bf).to_bits(), (a << frac) ^ (b << frac));
897            assert_eq!((-af).to_bits(), -(a << frac));
898            assert_eq!((!af).to_bits(), !(a << frac));
899            assert_eq!((af << 4u8).to_bits(), (a << frac) << 4);
900            assert_eq!((af >> 4i128).to_bits(), (a << frac) >> 4);
901            assert_eq!((af * b).to_bits(), (a << frac) * b);
902            assert_eq!((b * af).to_bits(), (a << frac) * b);
903            assert_eq!((af / b).to_bits(), (a << frac) / b);
904            assert_eq!((af % b).to_bits(), (a << frac) % (b << frac));
905        }
906    }
907
908    #[test]
909    fn fixed_u128() {
910        use crate::types::{U0F128, U121F7, U128F0};
911
912        let frac = U121F7::FRAC_NBITS;
913        let a = 0x0003_4567_89ab_cdef_0123_4567_89ab_cdef_u128;
914        let b = 5;
915        for &(a, b) in &[(a, b), (b, a)] {
916            let af = U121F7::from_num(a);
917            let bf = U121F7::from_num(b);
918            assert_eq!((af + bf).to_bits(), (a << frac) + (b << frac));
919            if a > b {
920                assert_eq!((af - bf).to_bits(), (a << frac) - (b << frac));
921            }
922            assert_eq!((af * bf).to_bits(), (a << frac) * b);
923            assert_eq!((af / bf).to_bits(), (a << frac) / b);
924            assert_eq!((af % bf).to_bits(), (a << frac) % (b << frac));
925            assert_eq!((af & bf).to_bits(), (a << frac) & (b << frac));
926            assert_eq!((af | bf).to_bits(), (a << frac) | (b << frac));
927            assert_eq!((af ^ bf).to_bits(), (a << frac) ^ (b << frac));
928            assert_eq!((!af).to_bits(), !(a << frac));
929            assert_eq!((af << 4u8).to_bits(), (a << frac) << 4);
930            assert_eq!((af >> 4i128).to_bits(), (a << frac) >> 4);
931            assert_eq!((af * b).to_bits(), (a << frac) * b);
932            assert_eq!((b * af).to_bits(), (a << frac) * b);
933            assert_eq!((af / b).to_bits(), (a << frac) / b);
934            assert_eq!((af % b).to_bits(), (a << frac) % (b << frac));
935
936            let af = U0F128::from_bits(a);
937            let bf = U0F128::from_bits(b);
938            assert_eq!(af * bf, 0);
939            assert_eq!(af * b, U0F128::from_bits(a * b));
940            assert_eq!(a * bf, U0F128::from_bits(a * b));
941            assert_eq!(bf * af, 0);
942
943            let af = U128F0::from_num(a);
944            let bf = U128F0::from_num(b);
945            assert_eq!(af * bf, a * b);
946            assert_eq!(af * b, a * b);
947            assert_eq!(a * bf, a * b);
948            assert_eq!(bf * af, a * b);
949            assert_eq!(af / bf, a / b);
950            assert_eq!(af / b, a / b);
951            assert_eq!(af % bf, a % b);
952            assert_eq!(af % b, a % b);
953        }
954    }
955
956    #[test]
957    fn fixed_i128() {
958        use crate::types::{I0F128, I121F7, I128F0};
959
960        let frac = I121F7::FRAC_NBITS;
961        let a = 0x0003_4567_89ab_cdef_0123_4567_89ab_cdef_i128;
962        let b = 5;
963        for &(a, b) in &[
964            (a, b),
965            (a, -b),
966            (-a, b),
967            (-a, -b),
968            (b, a),
969            (b, -a),
970            (-b, a),
971            (-b, -a),
972        ] {
973            let af = I121F7::from_num(a);
974            let bf = I121F7::from_num(b);
975            assert_eq!((af + bf).to_bits(), (a << frac) + (b << frac));
976            assert_eq!((af - bf).to_bits(), (a << frac) - (b << frac));
977            assert_eq!((af * bf).to_bits(), (a << frac) * b);
978            assert_eq!((af / bf).to_bits(), (a << frac) / b);
979            assert_eq!((af % bf).to_bits(), (a << frac) % (b << frac));
980            assert_eq!((af & bf).to_bits(), (a << frac) & (b << frac));
981            assert_eq!((af | bf).to_bits(), (a << frac) | (b << frac));
982            assert_eq!((af ^ bf).to_bits(), (a << frac) ^ (b << frac));
983            assert_eq!((-af).to_bits(), -(a << frac));
984            assert_eq!((!af).to_bits(), !(a << frac));
985            assert_eq!((af << 4u8).to_bits(), (a << frac) << 4);
986            assert_eq!((af >> 4i128).to_bits(), (a << frac) >> 4);
987            assert_eq!((af * b).to_bits(), (a << frac) * b);
988            assert_eq!((b * af).to_bits(), (a << frac) * b);
989            assert_eq!((af / b).to_bits(), (a << frac) / b);
990            assert_eq!((af % b).to_bits(), (a << frac) % (b << frac));
991
992            let af = I0F128::from_bits(a);
993            let bf = I0F128::from_bits(b);
994            let prod = if a.is_negative() == b.is_negative() {
995                I0F128::ZERO
996            } else {
997                -I0F128::DELTA
998            };
999            assert_eq!(af * bf, prod);
1000            assert_eq!(af * b, I0F128::from_bits(a * b));
1001            assert_eq!(a * bf, I0F128::from_bits(a * b));
1002            assert_eq!(bf * af, prod);
1003
1004            let af = I128F0::from_num(a);
1005            let bf = I128F0::from_num(b);
1006            assert_eq!(af * bf, a * b);
1007            assert_eq!(af * b, a * b);
1008            assert_eq!(a * bf, a * b);
1009            assert_eq!(bf * af, a * b);
1010            assert_eq!(af / bf, a / b);
1011            assert_eq!(af / b, a / b);
1012            assert_eq!(af % bf, a % b);
1013            assert_eq!(af % b, a % b);
1014        }
1015    }
1016
1017    fn check_rem_int(a: i32, b: i32) {
1018        use crate::types::I16F16;
1019        assert_eq!(I16F16::from_num(a) % b, a % b);
1020        assert_eq!(I16F16::from_num(a).rem_euclid_int(b), a.rem_euclid(b));
1021        match (I16F16::from_num(a).checked_rem_int(b), a.checked_rem(b)) {
1022            (Some(a), Some(b)) => assert_eq!(a, b),
1023            (None, None) => {}
1024            (a, b) => panic!("mismatch {a:?}, {b:?}"),
1025        }
1026        match (
1027            I16F16::from_num(a).checked_rem_euclid_int(b),
1028            a.checked_rem_euclid(b),
1029        ) {
1030            (Some(a), Some(b)) => assert_eq!(a, b),
1031            (None, None) => {}
1032            (a, b) => panic!("mismatch {a:?}, {b:?}"),
1033        }
1034    }
1035
1036    #[test]
1037    #[allow(clippy::modulo_one)]
1038    fn rem_int() {
1039        use crate::types::{I0F32, I1F31, I16F16};
1040        check_rem_int(-0x8000, -0x8000);
1041        check_rem_int(-0x8000, -0x7fff);
1042        check_rem_int(-0x8000, 0x7fff);
1043        check_rem_int(-0x8000, 0x8000);
1044        check_rem_int(-0x7fff, -0x8000);
1045        check_rem_int(-0x7fff, -0x7fff);
1046        check_rem_int(-0x7fff, 0x7fff);
1047        check_rem_int(-0x7fff, 0x8000);
1048        check_rem_int(0x7fff, -0x8000);
1049        check_rem_int(0x7fff, -0x7fff);
1050        check_rem_int(0x7fff, 0x7fff);
1051        check_rem_int(0x7fff, 0x8000);
1052
1053        fn i1(f: f32) -> I1F31 {
1054            I1F31::from_num(f)
1055        }
1056        fn i0(f: f32) -> I0F32 {
1057            I0F32::from_num(f)
1058        }
1059
1060        assert_eq!(I16F16::MIN % -1, 0);
1061        assert_eq!(I16F16::MIN.checked_rem_int(-1).unwrap(), 0);
1062        assert_eq!(I16F16::MIN.rem_euclid_int(-1), 0);
1063        assert_eq!(I16F16::MIN.checked_rem_euclid_int(-1).unwrap(), 0);
1064
1065        assert_eq!(i1(-1.0) % 1, i1(0.0));
1066        assert_eq!(i1(-1.0).rem_euclid_int(1), i1(0.0));
1067
1068        assert_eq!(i1(-0.75) % 1, i1(-0.75));
1069        assert_eq!(i1(-0.75).rem_euclid_int(1), i1(0.25));
1070
1071        assert_eq!(i1(-0.5) % 1, i1(-0.5));
1072        assert_eq!(i1(-0.5).rem_euclid_int(1), i1(0.5));
1073
1074        assert_eq!(i1(-0.5) % 3, i1(-0.5));
1075        assert_eq!(i1(-0.5).checked_rem_euclid_int(3), None);
1076        assert_eq!(i1(-0.5).wrapping_rem_euclid_int(3), i1(0.5));
1077        assert_eq!(i1(-0.5).overflowing_rem_euclid_int(3), (i1(0.5), true));
1078
1079        assert_eq!(i1(-0.25) % 1, i1(-0.25));
1080        assert_eq!(i1(-0.25).rem_euclid_int(1), i1(0.75));
1081
1082        assert_eq!(i1(-0.25) % 3, i1(-0.25));
1083        assert_eq!(i1(-0.25).checked_rem_euclid_int(3), None);
1084        assert_eq!(i1(-0.25).wrapping_rem_euclid_int(3), i1(0.75));
1085        assert_eq!(i1(-0.25).overflowing_rem_euclid_int(3), (i1(0.75), true));
1086
1087        assert_eq!(i1(0.0) % 1, i1(0.0));
1088        assert_eq!(i1(0.0).rem_euclid_int(1), i1(0.0));
1089
1090        assert_eq!(i1(0.25) % 1, i1(0.25));
1091        assert_eq!(i1(0.25).rem_euclid_int(1), i1(0.25));
1092
1093        assert_eq!(i1(0.5) % 1, i1(0.5));
1094        assert_eq!(i1(0.5).rem_euclid_int(1), i1(0.5));
1095
1096        assert_eq!(i1(0.75) % 1, i1(0.75));
1097        assert_eq!(i1(0.75).rem_euclid_int(1), i1(0.75));
1098
1099        assert_eq!(i0(-0.5) % 1, i0(-0.5));
1100        assert_eq!(i0(-0.5).checked_rem_euclid_int(1), None);
1101        assert_eq!(i0(-0.5).wrapping_rem_euclid_int(1), i0(-0.5));
1102        assert_eq!(i0(-0.5).overflowing_rem_euclid_int(1), (i0(-0.5), true));
1103
1104        assert_eq!(i0(-0.375) % 1, i0(-0.375));
1105        assert_eq!(i0(-0.375).checked_rem_euclid_int(1), None);
1106        assert_eq!(i0(-0.375).wrapping_rem_euclid_int(1), i0(-0.375));
1107        assert_eq!(i0(-0.375).overflowing_rem_euclid_int(1), (i0(-0.375), true));
1108
1109        assert_eq!(i0(-0.25) % 1, i0(-0.25));
1110        assert_eq!(i0(-0.25).checked_rem_euclid_int(1), None);
1111        assert_eq!(i0(-0.25).wrapping_rem_euclid_int(1), i0(-0.25));
1112        assert_eq!(i0(-0.25).overflowing_rem_euclid_int(1), (i0(-0.25), true));
1113
1114        assert_eq!(i0(0.0) % 1, i0(0.0));
1115        assert_eq!(i0(0.0).rem_euclid_int(1), i0(0.0));
1116
1117        assert_eq!(i0(0.25) % 1, i0(0.25));
1118        assert_eq!(i0(0.25).rem_euclid_int(1), i0(0.25));
1119    }
1120
1121    #[test]
1122    fn div_rem_nonzerou() {
1123        use crate::types::{U0F32, U1F31, U16F16, U31F1, U32F0};
1124        use core::num::NonZeroU32;
1125        let half_bits = u32::from(u16::MAX);
1126        let vals = &[
1127            0,
1128            1,
1129            100,
1130            5555,
1131            half_bits - 1,
1132            half_bits,
1133            half_bits + 1,
1134            u32::MAX - 1,
1135            u32::MAX,
1136        ];
1137        for &a in vals {
1138            for &b in vals {
1139                let a0 = U0F32::from_bits(a);
1140                let a1 = U1F31::from_bits(a);
1141                let a16 = U16F16::from_bits(a);
1142                let a31 = U31F1::from_bits(a);
1143                let a32 = U32F0::from_bits(a);
1144                let Some(nz) = NonZeroU32::new(b) else {
1145                    continue;
1146                };
1147                assert_eq!(a0 / nz, a0 / b);
1148                assert_eq!(a0 % nz, a0 % b);
1149                assert_eq!(a1 / nz, a1 / b);
1150                assert_eq!(a1 % nz, a1 % b);
1151                assert_eq!(a16 / nz, a16 / b);
1152                assert_eq!(a16 % nz, a16 % b);
1153                assert_eq!(a31 / nz, a31 / b);
1154                assert_eq!(a31 % nz, a31 % b);
1155                assert_eq!(a32 / nz, a32 / b);
1156                assert_eq!(a32 % nz, a32 % b);
1157            }
1158        }
1159    }
1160
1161    #[test]
1162    fn rem_nonzeroi() {
1163        use crate::types::{I0F32, I1F31, I16F16, I31F1, I32F0};
1164        use core::num::NonZeroI32;
1165        let vals = &[
1166            i32::MIN,
1167            i32::MIN + 1,
1168            -5555,
1169            -80,
1170            -1,
1171            0,
1172            1,
1173            100,
1174            5555,
1175            i32::MAX - 1,
1176            i32::MAX,
1177        ];
1178        for &a in vals {
1179            for &b in vals {
1180                let a0 = I0F32::from_bits(a);
1181                let a1 = I1F31::from_bits(a);
1182                let a16 = I16F16::from_bits(a);
1183                let a31 = I31F1::from_bits(a);
1184                let a32 = I32F0::from_bits(a);
1185                let Some(nz) = NonZeroI32::new(b) else {
1186                    continue;
1187                };
1188                assert_eq!(a0 % nz, a0 % b);
1189                assert_eq!(a1 % nz, a1 % b);
1190                assert_eq!(a16 % nz, a16 % b);
1191                assert_eq!(a31 % nz, a31 % b);
1192                assert_eq!(a32 % nz, a32 % b);
1193            }
1194        }
1195    }
1196
1197    macro_rules! check_mul_add {
1198        ($($F:ty)*) => { $(
1199            let min = <$F>::MIN;
1200            let max = <$F>::MAX;
1201            let hmax = max / 2;
1202            let delta = <$F>::DELTA;
1203            let zero = <$F>::ZERO;
1204            let one = <$F>::ONE;
1205            let three = one * 3;
1206            let m_hmax = zero.wrapping_sub(hmax);
1207            let m_delta = zero.wrapping_sub(delta);
1208            let max_m_delta = max - delta;
1209            assert_eq!(max.overflowing_mul_add(one, zero), (max, false));
1210            assert_eq!(max.overflowing_mul_add(one, delta), (min, true));
1211            assert_eq!(max.overflowing_mul_add(one, m_delta), (max_m_delta, m_delta > 0));
1212            assert_eq!(max.overflowing_mul_add(three, max), (<$F>::from_bits(!0 << 2), true));
1213            assert_eq!(hmax.overflowing_mul_add(three, m_hmax), (hmax * 2, m_hmax > 0));
1214        )* };
1215    }
1216
1217    macro_rules! check_mul_add_no_int {
1218        ($($F:ty)*) => { $(
1219            let min = <$F>::MIN;
1220            let max = <$F>::MAX;
1221            let hmax = max / 2;
1222            let delta = <$F>::DELTA;
1223            let zero = <$F>::ZERO;
1224            let quarter = delta << (<$F>::FRAC_NBITS - 2);
1225            assert_eq!(max.overflowing_mul_add(quarter, zero), (max >> 2, false));
1226            if <$F>::IS_SIGNED {
1227                assert_eq!(max.overflowing_mul_add(max, zero), (hmax, false));
1228                assert_eq!(max.overflowing_mul_add(max, max), (min + hmax - delta, true));
1229            } else {
1230                assert_eq!(max.overflowing_mul_add(max, zero), (max - delta, false));
1231                assert_eq!(max.overflowing_mul_add(max, max), (max - 2 * delta, true));
1232            }
1233        )* };
1234    }
1235
1236    #[test]
1237    fn mul_add() {
1238        use crate::types::*;
1239        check_mul_add! { I3F5 I3F13 I3F29 I3F61 I3F125 }
1240        check_mul_add! { I4F4 I8F8 I16F16 I32F32 I64F64 }
1241        check_mul_add! { I8F0 I16F0 I32F0 I64F0 I128F0 }
1242        check_mul_add! { U2F6 U2F14 U2F30 U2F62 U2F126 }
1243        check_mul_add! { U4F4 U8F8 U16F16 U32F32 U64F64 }
1244        check_mul_add! { U8F0 U16F0 U32F0 U64F0 U128F0 }
1245
1246        check_mul_add_no_int! { I0F8 I0F16 I0F32 I0F64 I0F128 }
1247        check_mul_add_no_int! { U0F8 U0F16 U0F32 U0F64 U0F128 }
1248    }
1249
1250    #[test]
1251    fn overflowing_mul_add_large_frac_nbits() {
1252        let nbits_2 = 128;
1253
1254        let max = u64::MAX;
1255
1256        assert_eq!(
1257            arith::u64::overflowing_mul_add(max, max, max, nbits_2),
1258            (max, false)
1259        );
1260        assert_eq!(
1261            arith::u64::overflowing_mul_add(max, max, max, nbits_2 - 1),
1262            (0, true)
1263        );
1264        assert_eq!(
1265            arith::u64::overflowing_mul_add(max, max, max - 1, nbits_2 - 1),
1266            (max, false)
1267        );
1268
1269        let (min, max) = (i64::MIN, i64::MAX);
1270
1271        assert_eq!(
1272            arith::i64::overflowing_mul_add(max, max, max, nbits_2 - 2),
1273            (max, false)
1274        );
1275        assert_eq!(
1276            arith::i64::overflowing_mul_add(max, max, max, nbits_2 - 3),
1277            (min, true)
1278        );
1279        assert_eq!(
1280            arith::i64::overflowing_mul_add(max, max, max - 1, nbits_2 - 3),
1281            (max, false)
1282        );
1283
1284        assert_eq!(
1285            arith::i64::overflowing_mul_add(min, min, max, nbits_2 - 1),
1286            (max, false)
1287        );
1288        assert_eq!(
1289            arith::i64::overflowing_mul_add(min, min, max, nbits_2 - 2),
1290            (min, true)
1291        );
1292        assert_eq!(
1293            arith::i64::overflowing_mul_add(min, min, max - 1, nbits_2 - 2),
1294            (max, false)
1295        );
1296
1297        assert_eq!(
1298            arith::i64::overflowing_mul_add(max, min, -max, nbits_2 - 2),
1299            (min, false)
1300        );
1301        assert_eq!(
1302            arith::i64::overflowing_mul_add(max, min, -max, nbits_2 - 3),
1303            (max, true)
1304        );
1305        assert_eq!(
1306            arith::i64::overflowing_mul_add(max, min, -max + 1, nbits_2 - 3),
1307            (min, false)
1308        );
1309
1310        let nbits_2 = 256;
1311
1312        let max = u128::MAX;
1313
1314        assert_eq!(
1315            arith::u128::overflowing_mul_add(max, max, max, nbits_2),
1316            (max, false)
1317        );
1318        assert_eq!(
1319            arith::u128::overflowing_mul_add(max, max, max, nbits_2 - 1),
1320            (0, true)
1321        );
1322        assert_eq!(
1323            arith::u128::overflowing_mul_add(max, max, max - 1, nbits_2 - 1),
1324            (max, false)
1325        );
1326
1327        let (min, max) = (i128::MIN, i128::MAX);
1328
1329        assert_eq!(
1330            arith::i128::overflowing_mul_add(max, max, max, nbits_2 - 2),
1331            (max, false)
1332        );
1333        assert_eq!(
1334            arith::i128::overflowing_mul_add(max, max, max, nbits_2 - 3),
1335            (min, true)
1336        );
1337        assert_eq!(
1338            arith::i128::overflowing_mul_add(max, max, max - 1, nbits_2 - 3),
1339            (max, false)
1340        );
1341
1342        assert_eq!(
1343            arith::i128::overflowing_mul_add(min, min, max, nbits_2 - 1),
1344            (max, false)
1345        );
1346        assert_eq!(
1347            arith::i128::overflowing_mul_add(min, min, max, nbits_2 - 2),
1348            (min, true)
1349        );
1350        assert_eq!(
1351            arith::i128::overflowing_mul_add(min, min, max - 1, nbits_2 - 2),
1352            (max, false)
1353        );
1354
1355        assert_eq!(
1356            arith::i128::overflowing_mul_add(max, min, -max, nbits_2 - 2),
1357            (min, false)
1358        );
1359        assert_eq!(
1360            arith::i128::overflowing_mul_add(max, min, -max, nbits_2 - 3),
1361            (max, true)
1362        );
1363        assert_eq!(
1364            arith::i128::overflowing_mul_add(max, min, -max + 1, nbits_2 - 3),
1365            (min, false)
1366        );
1367    }
1368
1369    #[test]
1370    fn overflowing_mul_add_neg_frac_nbits() {
1371        let nbits = 64;
1372
1373        let (zero, one, max) = (0u64, 1u64, u64::MAX);
1374
1375        assert_eq!(
1376            arith::u64::overflowing_mul_add(zero, zero, max, -nbits),
1377            (max, false)
1378        );
1379        assert_eq!(
1380            arith::u64::overflowing_mul_add(one, one, max, -nbits),
1381            (max, true)
1382        );
1383        assert_eq!(
1384            arith::u64::overflowing_mul_add(one, one, zero, 1 - nbits),
1385            (max - max / 2, false)
1386        );
1387        assert_eq!(
1388            arith::u64::overflowing_mul_add(one, one, max, 1 - nbits),
1389            (max / 2, true)
1390        );
1391
1392        let (zero, one, min, max) = (0i64, 1i64, i64::MIN, i64::MAX);
1393
1394        assert_eq!(
1395            arith::i64::overflowing_mul_add(zero, zero, max, -nbits),
1396            (max, false)
1397        );
1398        assert_eq!(
1399            arith::i64::overflowing_mul_add(one, one, max, -nbits),
1400            (max, true)
1401        );
1402        assert_eq!(
1403            arith::i64::overflowing_mul_add(one, one, -one, 1 - nbits),
1404            (max, false)
1405        );
1406        assert_eq!(
1407            arith::i64::overflowing_mul_add(one, one, zero, 1 - nbits),
1408            (min, true)
1409        );
1410
1411        assert_eq!(
1412            arith::i64::overflowing_mul_add(-one, -one, max, -nbits),
1413            (max, true)
1414        );
1415        assert_eq!(
1416            arith::i64::overflowing_mul_add(-one, -one, -one, 1 - nbits),
1417            (max, false)
1418        );
1419        assert_eq!(
1420            arith::i64::overflowing_mul_add(-one, -one, zero, 1 - nbits),
1421            (min, true)
1422        );
1423
1424        assert_eq!(
1425            arith::i64::overflowing_mul_add(one, -one, max, -nbits),
1426            (max, true)
1427        );
1428        assert_eq!(
1429            arith::i64::overflowing_mul_add(one, -one, min, -nbits),
1430            (min, true)
1431        );
1432        assert_eq!(
1433            arith::i64::overflowing_mul_add(one, -one, zero, 1 - nbits),
1434            (min, false)
1435        );
1436        assert_eq!(
1437            arith::i64::overflowing_mul_add(one, -one, max, 1 - nbits),
1438            (-one, false)
1439        );
1440
1441        let nbits = 128;
1442
1443        let (zero, one, max) = (0u128, 1u128, u128::MAX);
1444
1445        assert_eq!(
1446            arith::u128::overflowing_mul_add(zero, zero, max, -nbits),
1447            (max, false)
1448        );
1449        assert_eq!(
1450            arith::u128::overflowing_mul_add(one, one, max, -nbits),
1451            (max, true)
1452        );
1453        assert_eq!(
1454            arith::u128::overflowing_mul_add(one, one, zero, 1 - nbits),
1455            (max - max / 2, false)
1456        );
1457        assert_eq!(
1458            arith::u128::overflowing_mul_add(one, one, max, 1 - nbits),
1459            (max / 2, true)
1460        );
1461
1462        let (zero, one, min, max) = (0i128, 1i128, i128::MIN, i128::MAX);
1463
1464        assert_eq!(
1465            arith::i128::overflowing_mul_add(zero, zero, max, -nbits),
1466            (max, false)
1467        );
1468        assert_eq!(
1469            arith::i128::overflowing_mul_add(one, one, max, -nbits),
1470            (max, true)
1471        );
1472        assert_eq!(
1473            arith::i128::overflowing_mul_add(one, one, -one, 1 - nbits),
1474            (max, false)
1475        );
1476        assert_eq!(
1477            arith::i128::overflowing_mul_add(one, one, zero, 1 - nbits),
1478            (min, true)
1479        );
1480
1481        assert_eq!(
1482            arith::i128::overflowing_mul_add(-one, -one, max, -nbits),
1483            (max, true)
1484        );
1485        assert_eq!(
1486            arith::i128::overflowing_mul_add(-one, -one, -one, 1 - nbits),
1487            (max, false)
1488        );
1489        assert_eq!(
1490            arith::i128::overflowing_mul_add(-one, -one, zero, 1 - nbits),
1491            (min, true)
1492        );
1493
1494        assert_eq!(
1495            arith::i128::overflowing_mul_add(one, -one, max, -nbits),
1496            (max, true)
1497        );
1498        assert_eq!(
1499            arith::i128::overflowing_mul_add(one, -one, min, -nbits),
1500            (min, true)
1501        );
1502        assert_eq!(
1503            arith::i128::overflowing_mul_add(one, -one, zero, 1 - nbits),
1504            (min, false)
1505        );
1506        assert_eq!(
1507            arith::i128::overflowing_mul_add(one, -one, max, 1 - nbits),
1508            (-one, false)
1509        );
1510    }
1511
1512    #[test]
1513    fn issue_26() {
1514        use crate::types::extra::{U120, U121, U122, U123, U124};
1515        use crate::{FixedI128, FixedU128};
1516
1517        // issue 26 is about FixedI128<U123>, the others are just some extra tests
1518
1519        let x: FixedI128<U120> = "-9.079999999999999999999".parse().unwrap();
1520        let squared = x.checked_mul(x).unwrap();
1521        assert!(82.44639 < squared && squared < 82.44641);
1522        let msquared = (-x).checked_mul(x).unwrap();
1523        assert!(-82.44641 < msquared && msquared < -82.44639);
1524        assert_eq!(x.checked_mul(-x), Some(msquared));
1525        assert_eq!((-x).checked_mul(-x), Some(squared));
1526
1527        // 82 requires 8 signed integer bits
1528        let x: FixedI128<U121> = "-9.079999999999999999999".parse().unwrap();
1529        assert!(x.checked_mul(x).is_none());
1530        assert!((-x).checked_mul(x).is_none());
1531        assert!(x.checked_mul(-x).is_none());
1532        assert!((-x).checked_mul(-x).is_none());
1533        let x: FixedI128<U122> = "-9.079999999999999999999".parse().unwrap();
1534        assert!(x.checked_mul(x).is_none());
1535        assert!((-x).checked_mul(x).is_none());
1536        assert!(x.checked_mul(-x).is_none());
1537        assert!((-x).checked_mul(-x).is_none());
1538        let x: FixedI128<U123> = "-9.079999999999999999999".parse().unwrap();
1539        assert!(x.checked_mul(x).is_none());
1540        assert!((-x).checked_mul(x).is_none());
1541        assert!(x.checked_mul(-x).is_none());
1542        assert!((-x).checked_mul(-x).is_none());
1543
1544        let x: Result<FixedI128<U124>, _> = "-9.079999999999999999999".parse();
1545        assert!(x.is_err());
1546
1547        // Test unsigned
1548
1549        let x: FixedU128<U120> = "9.079999999999999999999".parse().unwrap();
1550        let squared = x.checked_mul(x).unwrap();
1551        assert!(82.44639 < squared && squared < 82.44641);
1552
1553        // 82 requires 8 signed integer bits
1554        let x: FixedU128<U122> = "9.079999999999999999999".parse().unwrap();
1555        assert!(x.checked_mul(x).is_none());
1556        let x: FixedU128<U123> = "9.079999999999999999999".parse().unwrap();
1557        assert!(x.checked_mul(x).is_none());
1558        let x: FixedU128<U124> = "9.079999999999999999999".parse().unwrap();
1559        assert!(x.checked_mul(x).is_none());
1560
1561        let x: Result<FixedI128<U125>, _> = "9.079999999999999999999".parse();
1562        assert!(x.is_err());
1563    }
1564
1565    #[test]
1566    fn issue_51() {
1567        use crate::types::*;
1568        // these are for the bug:
1569        assert_eq!(I0F8::MIN.overflowing_div(-I0F8::DELTA), (I0F8::ZERO, true));
1570        assert_eq!(
1571            I0F16::MIN.overflowing_div(-I0F16::DELTA),
1572            (I0F16::ZERO, true)
1573        );
1574        assert_eq!(
1575            I0F32::MIN.overflowing_div(-I0F32::DELTA),
1576            (I0F32::ZERO, true)
1577        );
1578        assert_eq!(
1579            I0F64::MIN.overflowing_div(-I0F64::DELTA),
1580            (I0F64::ZERO, true)
1581        );
1582        assert_eq!(
1583            I0F128::MIN.overflowing_div(-I0F128::DELTA),
1584            (I0F128::ZERO, true)
1585        );
1586        // some extra tests:
1587        assert_eq!(
1588            I0F32::MIN.overflowing_div(I0F32::DELTA),
1589            (I0F32::ZERO, true)
1590        );
1591        assert_eq!(I0F32::MIN.overflowing_div(I0F32::MIN), (I0F32::ZERO, true));
1592        assert_eq!(
1593            (-I0F32::MAX).overflowing_div(-I0F32::DELTA),
1594            (I0F32::ZERO, true)
1595        );
1596        assert_eq!(
1597            (-I0F32::MAX).overflowing_div(I0F32::DELTA),
1598            (I0F32::ZERO, true)
1599        );
1600        assert_eq!(
1601            (-I0F32::MAX).overflowing_div(I0F32::MIN),
1602            (I0F32::from_bits(-2), true)
1603        );
1604        assert_eq!(
1605            I0F128::MIN.overflowing_div(I0F128::DELTA),
1606            (I0F128::ZERO, true)
1607        );
1608        assert_eq!(
1609            I0F128::MIN.overflowing_div(I0F128::MIN),
1610            (I0F128::ZERO, true)
1611        );
1612        assert_eq!(
1613            (-I0F128::MAX).overflowing_div(-I0F128::DELTA),
1614            (I0F128::ZERO, true)
1615        );
1616        assert_eq!(
1617            (-I0F128::MAX).overflowing_div(I0F128::DELTA),
1618            (I0F128::ZERO, true)
1619        );
1620        assert_eq!(
1621            (-I0F128::MAX).overflowing_div(I0F128::MIN),
1622            (I0F128::from_bits(-2), true)
1623        );
1624    }
1625}