1use crate::{characters::*, ChineseNumeralBase, MidScaleInt, Sign, Signed};
2
3#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Debug, Default)]
7pub struct LongScaleInt {
8 pub(super) sign: Sign,
9 pub(super) data: u128,
10}
11
12impl LongScaleInt {
13 pub fn new_non_pos(abs: u128) -> Self {
17 if abs == 0 {
18 Self::default()
19 } else {
20 Self {
21 sign: Sign::Neg,
22 data: abs,
23 }
24 }
25 }
26}
27
28impl ChineseNumeralBase for LongScaleInt {
29 fn to_chars(&self) -> Vec<NumChar> {
30 let mut chars = Vec::new();
31 let mut num = *self.data();
32 let mut prev_rem = 1000_0000_0000_0000;
33
34 for exp in 14..=16 {
36 let rem = num % 1_0000_0000_0000_0000;
37 num /= 1_0000_0000_0000_0000;
38
39 if rem > 0 {
40 if !chars.is_empty() && prev_rem < 1000_0000_0000_0000 {
41 chars.push(NUM_CHARS[0]);
42 }
43 if exp > 14 {
44 chars.push(NUM_CHARS[exp]);
45 }
46 let mid = MidScaleInt::from(rem);
47 let mut node = mid.to_chars();
48 chars.append(&mut node);
49 }
50 prev_rem = rem;
51 }
52 chars
53 }
54
55 fn to_chars_trimmed(&self) -> Vec<NumChar> {
56 let mut chars = self.to_chars();
57 let mut data = *self.data();
58 while data >= 1_0000 {
59 data /= 1_0000;
60 }
61 if data >= 10 && data <= 19 {
62 let one = chars.pop();
63 debug_assert_eq!(one, Some(NumChar::One));
64 }
65 chars
66 }
67}
68
69#[cfg(feature = "bigint")]
70use num_bigint::BigUint;
71#[cfg(feature = "bigint")]
72use num_integer::Integer;
73#[cfg(feature = "bigint")]
74use num_traits::{ToPrimitive, Zero};
75
76#[cfg(feature = "bigint")]
80#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Debug, Default)]
81pub struct LongScaleBigInt {
82 pub(super) sign: Sign,
83 pub(super) data: BigUint,
84}
85
86#[cfg(feature = "bigint")]
87impl LongScaleBigInt {
88 pub(super) const MAX_ABS_ARR: &'static [u32] = &[
89 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295,
90 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295,
91 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295,
92 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295,
93 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295,
94 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295,
95 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295,
96 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295,
97 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295,
98 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295,
99 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295,
100 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295,
101 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295,
102 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295,
103 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295,
104 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295,
105 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295,
106 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295,
107 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295,
108 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295,
109 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295,
110 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295,
111 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295,
112 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295,
113 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295,
114 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295,
115 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295,
116 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295,
117 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295,
118 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295,
119 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295,
120 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295,
121 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295,
122 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295,
123 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295,
124 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295,
125 4294967295, 4294967295, 4294967295, 4294967295, 1691320320, 2671006246, 1682531301,
126 2072858707, 1240508969, 3108358191, 1125119096, 2470144952, 1610099978, 1690632660,
127 1941696884, 2663506355, 1006364675, 3909158537, 4147711374, 1072663936, 4078768933,
128 745751659, 4123687570, 471458681, 655028926, 4113407388, 3945524552, 985625313, 1254424514,
129 2127508744, 570530434, 945388122, 3194649404, 2589065070, 2731705399, 202030749,
130 2090780394, 3348662271, 1481754777, 1130635472, 4025144705, 1924486271, 2578567861,
131 125491448, 1558036315, 994248173, 3817216711, 763950077, 1030439870, 959586474, 3845661701,
132 483795093, 1637944470, 2275463649, 3398804829, 1758016486, 2665513698, 2004912571,
133 1094885097, 4223064276, 3307819021, 651121777, 1757003305, 3603542336, 129917786,
134 2215974994, 3042386306, 2205352757, 3944939700, 3710987569, 97967515, 1217242524,
135 930630949, 3660328512, 1787663098, 1784141600, 2500542892, 4034561586, 3444961378,
136 785043562, 3869499367, 885623728, 2625011087, 3053789617, 1965731793, 3900511934,
137 2648823592, 3851062028, 3321968688, 799195417, 1011847510, 1369129160, 1348009103,
138 2876796955, 2915408967, 3305284948, 263399535, 1715990604, 2645821294, 1587844552,
139 2624912049, 3035631499, 2306636348, 3499275462, 675152704, 854794152, 4004972748,
140 1739996642, 1333476491, 4012621867, 3658792931, 3297985728, 2864481726, 3066357406,
141 785287846, 1671499798, 433044045, 1919608025, 264833858, 3999983367, 1116778570,
142 1301982149, 4213901070, 4081649357, 536169226, 1389008649, 188923873, 373495152,
143 2551132278, 1800758715, 3951840330, 2632334454, 3118778225, 1034046547, 1862428410,
144 3037609062, 1994608505, 29051798, 2571685694, 264151332, 2260643090, 2717535964,
145 3508441116, 3283713017, 1903365635, 923575694, 1219598101, 2288281570, 3676533911,
146 1014136356, 555142354, 2389170030, 4185108175, 884862419, 836141292, 2957159173,
147 1997444768, 4233903127, 2876184692, 3089125070, 1480848293, 1097600237, 299700527,
148 2507669891, 2982628312, 2114881043, 2529576251, 2812279824, 2987750993, 4241938954,
149 2204775591, 1037094060, 829315638, 1231047149, 52608178, 3735136637, 3455232602, 962039123,
150 488286513, 50685385, 3516451821, 843975207, 1572355722, 675489076, 2428445672, 1555117248,
151 3708476086, 10375249, 4172112346, 2117510871, 2227658327, 3187664554, 3050656558,
152 328034318, 3179601324, 1247769761, 3439263953, 1431538938, 2962525068, 1213366289,
153 3813013550, 2651093719, 1860661503, 3933716208, 264320617, 789980519, 2257856172,
154 102000748, 977269860, 1113845122, 3008928583, 1461738106, 557786285, 2926560363,
155 1038106190, 3643478847, 828004507, 457818698, 1933056971, 373408056, 2076808229,
156 3160935130, 2781854874, 2519636100, 177606000, 4237103862, 3977834316, 1621936232,
157 2599050516, 319893558, 3343370366, 765044144, 976657331, 7026264, 294277429, 3829376742,
158 3029627280, 2705178718, 3614653880, 230519152, 3288033233, 293525479, 3805751881,
159 3227511198, 2520308544, 3648103003, 1111086184, 437622105, 2232033852, 3239146386,
160 584244184, 1450926016, 2462430443, 3226534010, 298582169, 4214576928, 1762099469,
161 964985185, 1585788148, 1641127666, 787006566, 2315956284, 3258232694, 2275058964,
162 2541003317, 1508235863, 2613339827, 4080647514, 1152057965, 3149266279, 731345410,
163 914737650, 65395712, 1884566942, 1379520432, 2611027720, 4163073378, 2619704967,
164 2746552541, 1388822415, 3005141199, 843440249, 4288674003, 3136174279, 4051522914,
165 4144149433, 3427566947, 3419023197, 3758479825, 3893877676, 96899594, 1657725776,
166 253618880, 434129337, 1499045748, 2996992534, 4036042074, 2110713869, 906222950, 928326225,
167 2541827893, 1604330202, 226792470, 4022228930, 815850898, 1466012310, 3377712199,
168 292769859, 2822055597, 3225701344, 3052947004, 385831222, 705324593, 4030158636,
169 3540280538, 2982120874, 2136414455, 255762046, 3852783591, 3262064164, 2358991588,
170 3756586117, 4143612643, 3326743817, 2897365738, 807711264, 3719310016, 3721264861,
171 3627337076, 944539331, 3640975513, 3712525681, 1162911839, 2008243316, 2179489649,
172 2867584109, 261861553, 3570253908, 2062868357, 2220328623, 3857004679, 3744109002,
173 4138041873, 1451860932, 2364975637, 2802161722, 2680106834, 753401584, 1223182946,
174 1245401957, 4163377735, 3565815922, 2216942838, 4036140094, 71979081, 3924559643,
175 400477238, 551750683, 1174153235, 859969898, 1185921017, 1711399735, 812991545, 4051735761,
176 3549118738, 1631653329, 3631835958, 3648867800, 1206500363, 2155893137, 361030362,
177 3454286017, 2505909489, 1083595169, 453595313, 1510564703, 1706163902, 1632924345,
178 1381875722, 1661526119, 1082778324, 3571910052, 1140625929, 851544870, 1145546234,
179 2938573139, 907528924, 1304752338, 1764668294, 1788942063, 1700368828, 104979467,
180 1413911959, 3327497828, 1956384744, 1272712474, 2815637534, 3307809377, 1320574940,
181 1111968962, 4073107827, 434096622, 169451929, 3201183459, 3331028877, 2852366972,
182 3369830128, 2924794558, 3106537952, 3739481231, 1612955817, 4138608722, 2721281595,
183 2755775390, 843505117, 982234295, 1157276611, 814674632, 4246504726, 3532006708, 992340967,
184 1647538031, 204696133, 193866982, 3899126129, 300851698, 1379496684, 1759463683,
185 1354782756, 1374637239, 3410883240, 1073406229, 3038431791, 1053909855, 3607043270,
186 173719711, 3733903830, 171820911, 1573050589, 932781534, 4183534770, 2158849555, 372245998,
187 3573073830, 841339264, 2759200520, 1610547277, 2603293319, 3890906486, 1557138278,
188 3964109906, 677238797, 537994297, 1124184993, 4287078344, 4207654540, 2943022776,
189 2977947524, 3255359985, 4098397558, 2274666217, 2915862060, 243524940, 2467726756,
190 2869020032, 507521339, 3403121914, 522051455, 1803903108, 3471254194, 473535371,
191 1948602036, 3352095732, 3116527002, 1795743673, 775867940, 2551469548, 3757442064,
192 3162525227, 3765412747, 3040105484, 1927625810, 48214767, 2997207130, 1342349989,
193 2536583992, 1501320191, 3592287317, 887432730, 967585477, 3334212779, 948663609,
194 1064513472, 15386372, 2465931737, 3230242590, 3036652803, 2063155087, 1927500726,
195 2821790499, 2187774383, 501520074, 3688568496, 3606711121, 2576459247, 3176542345,
196 378322447, 156541411, 1400607301, 1406179107, 677848877, 2253753529, 193196070, 4207435024,
197 4166396241, 509467541, 2906024136, 1221753746, 3375413222, 431327897, 2749265123,
198 2848827671, 3412997614, 2051920238, 1283516885, 1300498239, 1957256104, 2634010560,
199 3531900395, 360276850, 1461184973, 2012063967, 2873572430, 2914608609, 4289554777,
200 1539331673, 1859532928, 4213441063, 538215691, 3512720863, 4258743698, 3040408445,
201 982396546, 343095663, 4138069496, 1021581857, 214185242, 1968079460, 2864275059,
202 3347192726, 4096783459, 3259169450, 3707808869, 142485006, 399610869, 230556456,
203 2219467721, 4191227798, 2242548189, 3136366572, 179755707, 3464881829, 452317775,
204 3887426070, 3446430233, 1473370015, 1576807208, 3964523248, 419325089, 2373067114,
205 1596072055, 1928415752, 3635452689, 1005598891, 3335462724, 3290848636, 3669078247,
206 1178176812, 2110774376, 3068593619, 1253036518, 908857731, 3631223047, 4138506423,
207 2903592318, 3596915748, 3289036113, 3721512676, 2704409359, 3386016968, 3676268074,
208 2185259502, 1096257611, 3360076717, 3548676554, 170167319, 3360064287, 3899940843, 9640,
209 ];
210
211 pub fn max_value() -> Self {
213 Self {
214 sign: Sign::Pos,
215 data: BigUint::from_slice(Self::MAX_ABS_ARR),
216 }
217 }
218
219 pub fn min_value() -> Self {
221 Self {
222 sign: Sign::Neg,
223 data: BigUint::from_slice(Self::MAX_ABS_ARR),
224 }
225 }
226}
227
228#[cfg(feature = "bigint")]
229impl ChineseNumeralBase for LongScaleBigInt {
230 fn to_chars(&self) -> Vec<NumChar> {
231 let mut chars = Vec::new();
232 let mut num = self.data().to_owned();
233 let mut prev_rem = BigUint::new(vec![2764472320, 232830]);
235 let mut lim = BigUint::new(vec![2764472320, 232830]);
236 let mut div = BigUint::new(vec![1874919424, 2328306]);
238 let ten = BigUint::new(vec![10]);
239
240 for exp in 14..=23 {
241 let (_, rem) = num.div_rem(&div);
242 num /= ÷
243
244 if rem > BigUint::zero() {
245 if !chars.is_empty() && prev_rem < lim {
246 chars.push(NUM_CHARS[0]);
247 }
248 if exp > 14 {
249 chars.push(NUM_CHARS[exp]);
250 }
251 let mut node = if exp <= 15 {
252 let rem = rem.to_u64().unwrap();
253 let mid = MidScaleInt::from(rem);
254 mid.to_chars()
255 } else {
256 let long = Self::try_from(&rem).unwrap();
257 long.to_chars()
258 };
259 chars.append(&mut node);
260 }
261 prev_rem = rem;
262 if exp > 14 {
263 prev_rem *= ÷
264 div = &div * ÷
265 lim = &div / &ten;
266 }
267 }
268 chars
269 }
270
271 fn to_chars_trimmed(&self) -> Vec<NumChar> {
272 let mut chars = self.to_chars();
273 let mut data = self.data().to_owned();
274 let div = BigUint::new(vec![1_0000]);
275 let ten = BigUint::new(vec![10]);
276 let nineteen = BigUint::new(vec![19]);
277 while data >= div {
278 data /= ÷
279 }
280 if data >= ten && data <= nineteen {
281 let one = chars.pop();
282 debug_assert_eq!(one, Some(NumChar::One));
283 }
284 chars
285 }
286}