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