1use 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 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 let frac_nbits = Self::FRAC_NBITS;
488 let rhs = rhs.get();
489 if frac_nbits == <$Inner>::BITS {
490 return self;
492 }
493 let rhs_fixed_bits = rhs << frac_nbits;
494 if (rhs_fixed_bits >> frac_nbits) != rhs {
495 return self;
497 }
498 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 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 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 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 #[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 #[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 #[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 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 #[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 #[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 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 #[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 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 #[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 #[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 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 #[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 const fn overflowing_div_nz(lhs: i128, rhs: NonZeroI128, frac_nbits: u32) -> (i128, bool) {
818 let lhs2 = if frac_nbits == 128 {
819 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 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 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 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 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 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 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}