smart_big_rational/
util.rs1use std::ops::{Div, Rem, Shr};
16
17#[derive(Debug, Default, Clone, Copy)]
18pub struct OddDivider<T> {
19 pub divisor: T,
21 pub multiplier: T,
23 pub shift: u32,
25}
26
27impl<T> OddDivider<T>
28where
29 T: Copy + Shr<u32, Output = T> + Div<Output = T> + Rem<Output = T> + Arithmetic,
30{
31 #[inline(always)]
33 fn div_non_power_of_two(&self, x: T) -> T {
34 let (_, hi) = x.widening_mul(self.multiplier);
41 let y = ((x.wrapping_sub(hi)) >> 1).wrapping_add(hi);
42 y >> self.shift
43 }
44
45 #[inline(always)]
46 pub fn div_rem(&self, x: T) -> (T, T) {
47 let q = self.div_non_power_of_two(x);
48 let r = x.wrapping_sub(q.wrapping_mul(self.divisor));
49 (q, r)
50 }
51}
52
53pub trait Arithmetic: Sized {
54 fn wrapping_add(self, other: Self) -> Self;
55
56 fn wrapping_sub(self, other: Self) -> Self;
57
58 fn wrapping_mul(self, other: Self) -> Self;
59
60 fn widening_mul(self, other: Self) -> (Self, Self);
62}
63
64impl Arithmetic for u16 {
65 #[inline(always)]
66 fn wrapping_add(self, other: Self) -> Self {
67 self.wrapping_add(other)
68 }
69
70 #[inline(always)]
71 fn wrapping_sub(self, other: Self) -> Self {
72 self.wrapping_sub(other)
73 }
74
75 #[inline(always)]
76 fn wrapping_mul(self, other: Self) -> Self {
77 self.wrapping_mul(other)
78 }
79
80 #[inline(always)]
81 fn widening_mul(self, other: Self) -> (Self, Self) {
82 self.carrying_mul(other, 0)
83 }
84}
85
86impl Arithmetic for u32 {
87 #[inline(always)]
88 fn wrapping_add(self, other: Self) -> Self {
89 self.wrapping_add(other)
90 }
91
92 #[inline(always)]
93 fn wrapping_sub(self, other: Self) -> Self {
94 self.wrapping_sub(other)
95 }
96
97 #[inline(always)]
98 fn wrapping_mul(self, other: Self) -> Self {
99 self.wrapping_mul(other)
100 }
101
102 #[inline(always)]
103 fn widening_mul(self, other: Self) -> (Self, Self) {
104 self.carrying_mul(other, 0)
105 }
106}
107
108impl Arithmetic for u64 {
109 #[inline(always)]
110 fn wrapping_add(self, other: Self) -> Self {
111 self.wrapping_add(other)
112 }
113
114 #[inline(always)]
115 fn wrapping_sub(self, other: Self) -> Self {
116 self.wrapping_sub(other)
117 }
118
119 #[inline(always)]
120 fn wrapping_mul(self, other: Self) -> Self {
121 self.wrapping_mul(other)
122 }
123
124 #[inline(always)]
125 fn widening_mul(self, other: Self) -> (Self, Self) {
126 self.carrying_mul(other, 0)
127 }
128}