bigdecimal/arithmetic/
decimal.rs1#[allow(dead_code)]
10pub fn dec_shift_right_u32(x: u32, n: usize) -> u32 {
11 match n {
12 0 => x,
13 1 => x / 10,
14 2 => x / 100,
15 3 => x / 1000,
16 4 => x / 10_000,
17 5 => x / 100_000,
18 6 => x / 1000_000,
19 7 => x / 10_000_000,
20 8 => x / 100_000_000,
21 9 => x / 1000_000_000,
22 _ => 0,
23 }
24}
25
26
27#[allow(dead_code)]
29pub fn dec_shift_right_u64(x: u64, n: usize) -> u64 {
30 match n {
31 0 => x,
32 1 => x / 10,
33 2 => x / 100,
34 3 => x / 1000,
35 4 => x / 10_000,
36 5 => x / 100_000,
37 6 => x / 1000_000,
38 7 => x / 10_000_000,
39 8 => x / 100_000_000,
40 9 => x / 1000_000_000,
41 10 => x / 10_000_000_000,
42 11 => x / 100_000_000_000,
43 12 => x / 1000_000_000_000,
44 13 => x / 10_000_000_000_000,
45 14 => x / 100_000_000_000_000,
46 15 => x / 1000_000_000_000_000,
47 16 => x / 10_000_000_000_000_000,
48 17 => x / 100_000_000_000_000_000,
49 18 => x / 1000_000_000_000_000_000,
50 19 => x / 10_000_000_000_000_000_000,
51 _ => 0,
52 }
53}
54
55
56macro_rules! count_digits {
57 ($n:ident : u128) => {
58 if $n >= 100000000000000000000000000000000000000 {
59 39
60 } else if $n >= 10000000000000000000000000000000000000 {
61 38
62 } else if $n >= 1000000000000000000000000000000000000 {
63 37
64 } else if $n >= 100000000000000000000000000000000000 {
65 36
66 } else if $n >= 10000000000000000000000000000000000 {
67 35
68 } else if $n >= 1000000000000000000000000000000000 {
69 34
70 } else if $n >= 100000000000000000000000000000000 {
71 33
72 } else if $n >= 10000000000000000000000000000000 {
73 32
74 } else if $n >= 1000000000000000000000000000000 {
75 31
76 } else if $n >= 100000000000000000000000000000 {
77 30
78 } else if $n >= 10000000000000000000000000000 {
79 29
80 } else if $n >= 1000000000000000000000000000 {
81 28
82 } else if $n >= 100000000000000000000000000 {
83 27
84 } else if $n >= 10000000000000000000000000 {
85 26
86 } else if $n >= 1000000000000000000000000 {
87 25
88 } else if $n >= 100000000000000000000000 {
89 24
90 } else if $n >= 10000000000000000000000 {
91 23
92 } else if $n >= 1000000000000000000000 {
93 22
94 } else if $n >= 100000000000000000000 {
95 21
96 } else {
97 count_digits!($n:u64)
98 }
99 };
100 ($n:ident : u64) => {
101 if $n >= 10000000000000000000 {
102 20
103 } else if $n >= 1000000000000000000 {
104 19
105 } else if $n >= 100000000000000000 {
106 18
107 } else if $n >= 10000000000000000 {
108 17
109 } else if $n >= 1000000000000000 {
110 16
111 } else if $n >= 100000000000000 {
112 15
113 } else if $n >= 10000000000000 {
114 14
115 } else if $n >= 1000000000000 {
116 13
117 } else if $n >= 100000000000 {
118 12
119 } else if $n >= 10000000000 {
120 11
121 } else if $n >= 1000000000 {
122 10
123 } else {
124 count_digits!($n:u32)
125 }
126 };
127 ($n:ident : u32) => {
128 if $n >= 1000000000 {
129 10
130 } else if $n >= 100000000 {
131 9
132 } else if $n >= 10000000 {
133 8
134 } else if $n >= 1000000 {
135 7
136 } else if $n >= 100000 {
137 6
138 } else {
139 count_digits!($n:u16)
140 }
141 };
142 ($n:ident : u16) => {
143 if $n >= 100000 {
144 6
145 } else if $n >= 10000 {
146 5
147 } else if $n >= 1000 {
148 4
149 } else {
150 count_digits!($n:u8)
151 }
152 };
153 ($n:ident : u8) => {
154 if $n >= 100 {
155 3
156 } else if $n >= 10 {
157 2
158 } else {
159 1
160 }
161 };
162}
163
164pub(crate) fn count_digits_u32(n: u32) -> usize {
166 if n >= 1000000000 {
10
} else if n >= 100000000 {
9
} else if n >= 10000000 {
8
} else if n >= 1000000 {
7
} else if n >= 100000 {
6
} else {
if n >= 100000 {
6
} else if n >= 10000 {
5
} else if n >= 1000 {
4
} else { if n >= 100 { 3 } else if n >= 10 { 2 } else { 1 } }
}count_digits!(n:u32)
167
168}
169
170pub(crate) fn count_digits_u64(n: u64) -> usize {
172 if (n >> 32) == 0 {
173 count_digits_u32(n as u32)
174 } else {
175 if n >= 10000000000000000000 {
20
} else if n >= 1000000000000000000 {
19
} else if n >= 100000000000000000 {
18
} else if n >= 10000000000000000 {
17
} else if n >= 1000000000000000 {
16
} else if n >= 100000000000000 {
15
} else if n >= 10000000000000 {
14
} else if n >= 1000000000000 {
13
} else if n >= 100000000000 {
12
} else if n >= 10000000000 {
11
} else if n >= 1000000000 {
10
} else {
if n >= 1000000000 {
10
} else if n >= 100000000 {
9
} else if n >= 10000000 {
8
} else if n >= 1000000 {
7
} else if n >= 100000 {
6
} else {
if n >= 100000 {
6
} else if n >= 10000 {
5
} else if n >= 1000 {
4
} else { if n >= 100 { 3 } else if n >= 10 { 2 } else { 1 } }
}
}count_digits!(n:u64)
176 }
177}
178
179pub(crate) fn count_digits_u128(n: u128) -> usize {
181 if (n >> 64) == 0 {
182 count_digits_u64(n as u64)
183 } else {
184 if n >= 100000000000000000000000000000000000000 {
39
} else if n >= 10000000000000000000000000000000000000 {
38
} else if n >= 1000000000000000000000000000000000000 {
37
} else if n >= 100000000000000000000000000000000000 {
36
} else if n >= 10000000000000000000000000000000000 {
35
} else if n >= 1000000000000000000000000000000000 {
34
} else if n >= 100000000000000000000000000000000 {
33
} else if n >= 10000000000000000000000000000000 {
32
} else if n >= 1000000000000000000000000000000 {
31
} else if n >= 100000000000000000000000000000 {
30
} else if n >= 10000000000000000000000000000 {
29
} else if n >= 1000000000000000000000000000 {
28
} else if n >= 100000000000000000000000000 {
27
} else if n >= 10000000000000000000000000 {
26
} else if n >= 1000000000000000000000000 {
25
} else if n >= 100000000000000000000000 {
24
} else if n >= 10000000000000000000000 {
23
} else if n >= 1000000000000000000000 {
22
} else if n >= 100000000000000000000 {
21
} else {
if n >= 10000000000000000000 {
20
} else if n >= 1000000000000000000 {
19
} else if n >= 100000000000000000 {
18
} else if n >= 10000000000000000 {
17
} else if n >= 1000000000000000 {
16
} else if n >= 100000000000000 {
15
} else if n >= 10000000000000 {
14
} else if n >= 1000000000000 {
13
} else if n >= 100000000000 {
12
} else if n >= 10000000000 {
11
} else if n >= 1000000000 {
10
} else {
if n >= 1000000000 {
10
} else if n >= 100000000 {
9
} else if n >= 10000000 {
8
} else if n >= 1000000 {
7
} else if n >= 100000 {
6
} else {
if n >= 100000 {
6
} else if n >= 10000 {
5
} else if n >= 1000 {
4
} else { if n >= 100 { 3 } else if n >= 10 { 2 } else { 1 } }
}
}
}count_digits!(n:u128)
185 }
186}
187
188pub(crate) fn count_digits_bigint(n: &num_bigint::BigInt) -> u64 {
190 count_digits_biguint(n.magnitude())
191}
192
193pub(crate) fn count_digits_biguint(n: &num_bigint::BigUint) -> u64 {
195 use num_traits::ToPrimitive;
196
197 if let Some(n) = n.to_u64() {
198 return count_digits_u64(n) as u64;
199 }
200
201 let mut digits = (n.bits() as f64 / super::LOG2_10) as u64;
202 let mut num = super::ten_to_the_uint(digits);
204 if true {
if !(n * 10u8 >= num) {
::core::panicking::panic("assertion failed: n * 10u8 >= num")
};
};debug_assert!(n * 10u8 >= num);
205
206 while n >= &num {
207 num *= 10u8;
208 digits += 1;
209 }
210 digits
211}
212
213pub(crate) fn get_power_of_ten_u64(n: u64) -> Option<u8> {
215 match n {
216 0 => Some(0),
217 10 => Some(1),
218 100 => Some(2),
219 1000 => Some(3),
220 10000 => Some(4),
221 100000 => Some(5),
222 1000000 => Some(6),
223 10000000 => Some(7),
224 100000000 => Some(8),
225 1000000000 => Some(9),
226 10000000000 => Some(10),
227 n => {
228 let (q, r) = num_integer::div_rem(n, 10000000000);
229 if r == 0 {
230 get_power_of_ten_u64(q).map(|p| p + 10)
231 } else {
232 None
233 }
234 }
235 }
236}
237
238#[cfg(test)]
239mod test {
240 use super::*;
241 include!("decimal.tests.rs");
242}