1#![doc = include_str!("../README.md")]
2use rug::integer::IntegerExt64;
3use rug::ops::*;
4use rug::{Complete, Float, Integer};
5use std::ops::Mul;
6use std::ops::Rem;
7
8pub use rug;
9
10pub fn factorial(n: u64, k: u32) -> Integer {
12 Integer::factorial_m_64(n, k as u64).complete()
13}
14
15pub fn negative_multifacorial_factor(n: Integer, k: i32) -> Option<Integer> {
17 let n = -n;
18 let rem = n.rem(2 * (k as i64));
19 if rem == 0 {
20 None
21 } else if rem < k {
22 Some(Integer::ONE.clone())
23 } else if rem == k {
24 None
25 } else {
26 Some(Integer::NEG_ONE.clone())
27 }
28}
29
30pub fn subfactorial(n: u64) -> Integer {
32 let mut f = Integer::ONE.clone();
33 let mut b = true;
34 for i in 1..=n {
35 f *= Integer::from(i);
36 if b {
37 f -= Integer::ONE;
38 } else {
39 f += Integer::ONE;
40 }
41 b.not_assign();
42 }
43 f
44}
45
46pub fn termial(n: Integer) -> Integer {
48 (n.clone() * (n + 1)) / 2
49}
50
51pub fn multitermial(n: Integer, k: u32) -> Integer {
53 let modulo = n.mod_u(k);
54 let floor = n / k;
55 let ceil = floor.clone() + if modulo == 0 { 0 } else { 1 };
56 k * termial(floor) + ceil * modulo
57}
58
59pub fn fractional_factorial(x: Float) -> Float {
61 (x + 1.0f64).gamma()
62}
63
64pub fn fractional_multifactorial(x: Float, k: u32) -> Float {
69 let _k = k as i32;
70 let k = Float::with_val(x.prec(), k);
71 let fact = fractional_factorial(x.clone() / k.clone());
72 let pow = k.clone().pow(x.clone() / k.clone());
73 let t = if _k <= 7 {
74 fractional_multifactorial_product(x, _k, k)
75 } else {
76 fractional_multifactorial_product_fast(x, _k, k)
77 };
78 fact * pow * t
79}
80
81fn fractional_multifactorial_product(x: Float, _k: i32, k: Float) -> Float {
82 (1.._k)
83 .map(|j| {
84 let exp = fractional_multifactorial_sum(x.clone(), j, _k, k.clone());
85 (j / k.clone().pow(j / k.clone()) / fractional_factorial(j / k.clone())).pow(exp)
86 })
87 .reduce(Mul::mul)
88 .unwrap_or(Float::with_val(x.prec(), 1))
89}
90
91fn fractional_multifactorial_product_fast(x: Float, _k: i32, k: Float) -> Float {
92 (-3..=3)
93 .map(|n| {
94 ((x.to_integer().unwrap() + n - 1) as Integer)
95 .rem(_k - 1)
96 .to_i32()
97 .unwrap()
98 + 1
99 })
100 .map(|j| {
101 let exp = fractional_multifactorial_sum(x.clone(), j, _k, k.clone());
102 (j / k.clone().pow(j / k.clone()) / fractional_factorial(j / k.clone())).pow(exp)
103 })
104 .reduce(Mul::mul)
105 .unwrap_or(Float::with_val(x.prec(), 1))
106}
107
108fn fractional_multifactorial_sum(x: Float, j: i32, _k: i32, k: Float) -> Float {
109 (0.._k)
110 .filter(|l| *l != j)
111 .map(|l| 1 - Float::cos_pi(2 * ((x.clone() - l) / _k)))
112 .reduce(Mul::mul)
113 .unwrap_or(Float::with_val(x.prec(), 1))
114 / (1.._k)
115 .map(|l| 1 - Float::cos_pi(-2 * l / k.clone()))
116 .reduce(Mul::mul)
117 .unwrap_or(Float::with_val(x.prec(), 1))
118}
119
120pub fn fractional_termial(x: Float) -> Float {
122 let prec = x.prec();
123 let gamma_plus = ((x.clone() + 2) as Float).gamma();
124 let gamma_minus = ((x) as Float).gamma();
125 if !gamma_minus.is_finite() && gamma_plus.is_finite() {
126 return Float::new(prec);
127 }
128 (gamma_plus / gamma_minus) / 2
129}
130
131pub fn approximate_factorial(n: Integer, prec: u32) -> (Float, Integer) {
139 let n = Float::with_val(prec, n);
140 approximate_factorial_float(n)
141}
142pub fn approximate_factorial_float(n: Float) -> (Float, Integer) {
150 let prec = n.prec();
151 let base = n.clone() / Float::with_val(prec, 1).exp();
152 let ten_in_base = Float::with_val(prec, 10).ln() / base.clone().ln();
153 let (extra, _) = (n.clone() / ten_in_base.clone())
154 .to_integer_round(rug::float::Round::Down)
155 .unwrap_or_else(|| panic!("Got non-finite number, n was {n}"));
156 let exponent = n.clone() - ten_in_base * Float::with_val(prec, extra.clone());
157 let factorial = base.pow(exponent)
158 * (Float::with_val(prec, rug::float::Constant::Pi) * Float::with_val(prec, 2) * n.clone())
159 .sqrt();
160 let numerators: [f64; 17] = [
162 1.0,
163 1.0,
164 1.0,
165 -139.0,
166 -571.0,
167 163879.0,
168 5246819.0,
169 -534703531.0,
170 -4483131259.0,
171 432261921612371.0,
172 6232523202521089.0,
173 -25834629665134204969.0,
174 -1579029138854919086429.0,
175 746590869962651602203151.0,
176 1511513601028097903631961.0,
177 -8849272268392873147705987190261.0,
178 -142801712490607530608130701097701.0,
179 ];
180 let denominators: [f64; 17] = [
182 1.0,
183 12.0,
184 288.0,
185 51840.0,
186 2488320.0,
187 209018880.0,
188 75246796800.0,
189 902961561600.0,
190 86684309913600.0,
191 514904800886784000.0,
192 86504006548979712000.0,
193 13494625021640835072000.0,
194 9716130015581401251840000.0,
195 116593560186976815022080000.0,
196 2798245444487443560529920000.0,
197 299692087104605205332754432000000.0,
198 57540880724084199423888850944000000.0,
199 ];
200 let series_sum: Float = numerators
201 .into_iter()
202 .zip(denominators)
203 .enumerate()
204 .map(|(m, (num, den))| num / (den * n.clone().pow(m)))
205 .reduce(|a, e| a + e)
206 .unwrap_or(Float::new(prec));
207 let factorial = factorial * series_sum;
208 adjust_approximate((factorial, extra))
209}
210
211pub const APPROX_FACT_SAFE_UPPER_BOUND_FACTOR: u32 = 4_000_000;
212pub fn approximate_multifactorial(n: Integer, k: u32, prec: u32) -> (Float, Integer) {
219 let n = Float::with_val(prec, n);
220 approximate_multifactorial_float(n, k)
221}
222pub fn approximate_multifactorial_float(n: Float, k: u32) -> (Float, Integer) {
229 let prec = n.prec();
230 let k = Float::with_val(prec, k);
231 let fact = approximate_factorial_float(n.clone() / k.clone());
232 let pow = approximate_multifactorial_pow(n.clone(), k.clone());
233 let t = approximate_multifactorial_product(n, k);
234 adjust_approximate((fact.0 * pow.0 * t, fact.1 + pow.1))
235}
236fn approximate_multifactorial_pow(n: Float, k: Float) -> (Float, Integer) {
237 let base = n.clone() / k.clone();
238 let k_log10 = k.clone().log10();
239 let e = (base.clone() * k_log10.clone())
240 .to_integer_round(rug::float::Round::Down)
241 .unwrap()
242 .0;
243 let x = k.pow(base - e.clone() / k_log10);
244 (x, e)
245}
246fn approximate_multifactorial_product(n: Float, k: Float) -> Float {
247 let j: Float = ((n - 1) as Float).rem(&k) + 1;
248 j.clone() / k.clone().pow(j.clone() / k.clone()) / fractional_factorial(j.clone() / k.clone())
249}
250
251pub fn approximate_subfactorial(n: Integer, prec: u32) -> (Float, Integer) {
253 let n = Float::with_val(prec, n);
254 approximate_subfactorial_float(n)
255}
256pub fn approximate_subfactorial_float(n: Float) -> (Float, Integer) {
258 let prec = n.prec();
259 let (x, e) = approximate_factorial_float(n);
260 adjust_approximate((x / Float::with_val(prec, 1).exp(), e))
261}
262
263pub fn approximate_termial(n: Integer, k: u32, prec: u32) -> (Float, Integer) {
265 let n = Float::with_val(prec, n);
266 approximate_termial_float(k, n)
267}
268
269pub fn approximate_termial_float(k: u32, n: Float) -> (Float, Integer) {
271 let prec = n.prec();
272 let len: Integer = n
273 .clone()
274 .abs()
275 .log10()
276 .to_integer_round(rug::float::Round::Down)
277 .unwrap()
278 .0;
279 let len_10 = Float::with_val(prec, 10).pow(len.clone());
280 let a = n.clone() / len_10.clone();
281 let b = (n + k) / len_10;
282 adjust_approximate(((a * b) / (2 * Float::with_val(prec, k)), 2 * len))
283}
284
285pub fn approximate_approx_termial((x, e): (Float, Integer), k: u32) -> (Float, Integer) {
287 let a = x.clone();
288 let b = x + k;
289 adjust_approximate(((a * b) / (2 * k), 2 * e))
290}
291
292pub fn approximate_multifactorial_digits(n: Integer, k: u32, prec: u32) -> Integer {
301 let n = Float::with_val(prec, n);
302 approximate_multifactorial_digits_float(k, n)
303}
304pub fn approximate_multifactorial_digits_float(k: u32, n: Float) -> Integer {
313 let prec = n.prec();
314 let k = Float::with_val(prec, k);
315 let ln10 = Float::with_val(prec, 10).ln();
316 let base = n.clone().ln() / &ln10;
317 ((Float::with_val(prec, 0.5) + n.clone() / k.clone()) * base - n.clone() / k / ln10)
318 .to_integer_round(rug::float::Round::Down)
319 .unwrap_or_else(|| panic!("Got non-finite number, n was {n}"))
320 .0
321 + Integer::ONE
322}
323
324pub fn approximate_termial_digits(n: Integer, k: u32, prec: u32) -> Integer {
326 let n = Float::with_val(prec, n);
327 approximate_termial_digits_float(k, n)
328}
329pub fn approximate_termial_digits_float(k: u32, n: Float) -> Integer {
330 let prec = n.prec();
331 ((n.log10() * 2) as Float - Float::with_val(prec, 2 * k).log10())
332 .to_integer_round(rug::float::Round::Down)
333 .unwrap()
334 .0
335}
336
337pub fn adjust_approximate((x, e): (Float, Integer)) -> (Float, Integer) {
342 let prec = x.prec();
343 if x == 0.0 {
344 return (Float::with_val(prec, 0), Integer::ZERO.clone());
345 }
346 let (extra, _) = (x.clone().abs().ln() / Float::with_val(prec, 10).ln())
347 .to_integer_round(rug::float::Round::Down)
348 .unwrap_or_else(|| panic!("Got non-finite number, x was {x}"));
349 let x = x / (Float::with_val(prec, 10).pow(extra.clone()));
350 let total_exponent = extra + e;
351 (x, total_exponent)
352}
353
354pub fn length(n: &Integer, prec: u32) -> Integer {
356 if n == &0 {
357 return Integer::ONE.clone();
358 }
359
360 (Float::with_val(prec, n).abs().ln() / Float::with_val(prec, 10).ln())
361 .to_integer_round(rug::float::Round::Down)
362 .unwrap()
363 .0
364 + 1
365}
366
367pub mod recommended {
369 pub const FLOAT_PRECISION: u32 = 1024;
371}
372
373#[cfg(test)]
374mod tests {
375 use super::*;
376 use std::str::FromStr;
377
378 use recommended::FLOAT_PRECISION;
379
380 #[test]
381 fn test_calculate_multi_single_factorial() {
382 assert_eq!(factorial(0, 1), Integer::from(1));
383 assert_eq!(factorial(1, 1), Integer::from(1));
384 assert_eq!(factorial(2, 1), Integer::from(2));
385 assert_eq!(factorial(3, 1), Integer::from(6));
386 assert_eq!(factorial(4, 1), Integer::from(24));
387 assert_eq!(factorial(5, 1), Integer::from(120));
388 assert_eq!(factorial(6, 1), Integer::from(720));
389 assert_eq!(factorial(7, 1), Integer::from(5040));
390 assert_eq!(factorial(8, 1), Integer::from(40320));
391 assert_eq!(factorial(9, 1), Integer::from(362880));
392 assert_eq!(factorial(10, 1), Integer::from(3628800));
393 }
394
395 #[test]
396 fn test_calculate_multi_double_factorial() {
397 assert_eq!(factorial(0, 2), Integer::from(1));
398 assert_eq!(factorial(1, 2), Integer::from(1));
399 assert_eq!(factorial(2, 2), Integer::from(2));
400 assert_eq!(factorial(3, 2), Integer::from(3));
401 assert_eq!(factorial(4, 2), Integer::from(8));
402 assert_eq!(factorial(5, 2), Integer::from(15));
403 assert_eq!(factorial(6, 2), Integer::from(48));
404 assert_eq!(factorial(7, 2), Integer::from(105));
405 assert_eq!(factorial(8, 2), Integer::from(384));
406 assert_eq!(factorial(9, 2), Integer::from(945));
407 assert_eq!(factorial(10, 2), Integer::from(3840));
408 assert_eq!(
409 factorial(100, 2),
410 Integer::from_str(
411 "34243224702511976248246432895208185975118675053719198827915654463488000000000000"
412 )
413 .unwrap()
414 );
415 }
416
417 #[test]
418 fn test_calculate_triple_factorial() {
419 assert_eq!(factorial(0, 3), Integer::from(1));
420 assert_eq!(factorial(1, 3), Integer::from(1));
421 assert_eq!(factorial(2, 3), Integer::from(2));
422 assert_eq!(factorial(3, 3), Integer::from(3));
423 assert_eq!(factorial(4, 3), Integer::from(4));
424 assert_eq!(factorial(5, 3), Integer::from(10));
425 assert_eq!(factorial(6, 3), Integer::from(18));
426 assert_eq!(factorial(7, 3), Integer::from(28));
427 assert_eq!(factorial(8, 3), Integer::from(80));
428 assert_eq!(factorial(9, 3), Integer::from(162));
429 assert_eq!(factorial(10, 3), Integer::from(280));
430
431 assert_eq!(factorial(20, 3), Integer::from(4188800));
432 assert_eq!(factorial(22, 3), Integer::from(24344320));
433 assert_eq!(factorial(25, 3), Integer::from(608608000));
434 assert_eq!(
435 factorial(100, 3),
436 Integer::from_str("174548867015437739741494347897360069928419328000000000").unwrap()
437 );
438 }
439
440 #[test]
441 fn test_calculate_quadruple_factorial() {
442 assert_eq!(factorial(0, 4), Integer::from(1));
443 assert_eq!(factorial(1, 4), Integer::from(1));
444 assert_eq!(factorial(2, 4), Integer::from(2));
445 assert_eq!(factorial(3, 4), Integer::from(3));
446 assert_eq!(factorial(4, 4), Integer::from(4));
447 assert_eq!(factorial(5, 4), Integer::from(5));
448 assert_eq!(factorial(6, 4), Integer::from(12));
449 assert_eq!(factorial(7, 4), Integer::from(21));
450 assert_eq!(factorial(8, 4), Integer::from(32));
451 assert_eq!(factorial(9, 4), Integer::from(45));
452 assert_eq!(factorial(10, 4), Integer::from(120));
453
454 assert_eq!(factorial(20, 4), Integer::from(122880));
455 assert_eq!(factorial(22, 4), Integer::from(665280));
456 assert_eq!(factorial(25, 4), Integer::from(5221125));
457 assert_eq!(
458 factorial(100, 4),
459 Integer::from_str("17464069942802730897824646237782016000000").unwrap()
460 );
461 }
462
463 #[test]
464 fn test_calculate_quituple_factorial() {
465 assert_eq!(factorial(0, 5), Integer::from(1));
466 assert_eq!(factorial(1, 5), Integer::from(1));
467 assert_eq!(factorial(2, 5), Integer::from(2));
468 assert_eq!(factorial(3, 5), Integer::from(3));
469 assert_eq!(factorial(4, 5), Integer::from(4));
470 assert_eq!(factorial(5, 5), Integer::from(5));
471 assert_eq!(factorial(6, 5), Integer::from(6));
472 assert_eq!(factorial(7, 5), Integer::from(14));
473 assert_eq!(factorial(8, 5), Integer::from(24));
474 assert_eq!(factorial(9, 5), Integer::from(36));
475 assert_eq!(factorial(10, 5), Integer::from(50));
476
477 assert_eq!(factorial(15, 5), Integer::from(750));
478 assert_eq!(factorial(20, 5), Integer::from(15000));
479 assert_eq!(factorial(22, 5), Integer::from(62832));
480 assert_eq!(factorial(25, 5), Integer::from(375000));
481 assert_eq!(
482 factorial(100, 5),
483 Integer::from_str("232019615953125000000000000000000").unwrap()
484 );
485 }
486
487 #[test]
488 fn test_calculate_factorials_with_interesting_lengths() {
489 let result = factorial(22, 1);
490 assert_eq!(22, length(&result, FLOAT_PRECISION));
491
492 let result = factorial(23, 1);
493 assert_eq!(23, length(&result, FLOAT_PRECISION));
494
495 let result = factorial(24, 1);
496 assert_eq!(24, length(&result, FLOAT_PRECISION));
497
498 let result = factorial(82, 1);
499 assert_eq!(123, length(&result, FLOAT_PRECISION));
500
501 let result = factorial(3909, 1);
502 assert_eq!(12346, length(&result, FLOAT_PRECISION));
503
504 let result = factorial(574, 1);
505 assert_eq!(1337, length(&result, FLOAT_PRECISION));
506 }
507
508 #[test]
509 fn test_calculate_factorial_with_ten_thousand_digits() {
510 let mut num = 0;
511 let mut result = Integer::new();
512 while length(&result, FLOAT_PRECISION) < 10_000 {
513 num += 1;
514 result = factorial(num, 1);
515 }
516 assert_eq!(num, 3249);
517 }
518
519 #[test]
520 fn test_calculate_factorial_hundred_thousand() {
521 let num = 100_001;
522 let result = factorial(num, 1);
523 assert_eq!(length(&result, FLOAT_PRECISION), 456579);
524 }
525
526 #[test]
527 fn test_calculate_factorial_multilevel_hundred_thousand() {
528 let num = 100_001;
529 let result = factorial(num, 10);
530 assert_eq!(length(&result, FLOAT_PRECISION), 45660);
531 }
532
533 #[test]
541 fn test_calculate_subfactorial() {
542 assert_eq!(subfactorial(0), Integer::from(1));
543 assert_eq!(subfactorial(1), Integer::from_str("0").unwrap());
544 assert_eq!(subfactorial(2), Integer::from_str("1").unwrap());
545 assert_eq!(subfactorial(3), Integer::from_str("2").unwrap());
546 assert_eq!(subfactorial(4), Integer::from_str("9").unwrap());
547 assert_eq!(subfactorial(5), Integer::from_str("44").unwrap());
548 assert_eq!(subfactorial(6), Integer::from_str("265").unwrap());
549 assert_eq!(subfactorial(10), Integer::from_str("1334961").unwrap());
550 assert_eq!(subfactorial(12), Integer::from_str("176214841").unwrap());
551 assert_eq!(subfactorial(13), Integer::from_str("2290792932").unwrap());
552 assert_eq!(subfactorial(14), Integer::from_str("32071101049").unwrap());
553 assert_eq!(
554 subfactorial(20),
555 Integer::from_str("895014631192902121").unwrap()
556 );
557 assert_eq!(
558 subfactorial(21),
559 Integer::from_str("18795307255050944540").unwrap()
560 );
561 assert_eq!(
562 subfactorial(34),
563 Integer::from_str("108610077126170304674801654684367969729").unwrap()
564 );
565 assert_eq!(subfactorial(100), Integer::from_str("34332795984163804765195977526776142032365783805375784983543400282685180793327632432791396429850988990237345920155783984828001486412574060553756854137069878601").unwrap());
566 assert_eq!(subfactorial(1000), Integer::from_str("148030000371669080363916614118966054237787246771683461554691846089888817122236071181318987391054867545959072618913067395256592673937835956772241168222528295595683596720980666220609427831904885242029599391814586746492963217722340317777195575260366010059010655172144738284878861758208131004735035818477569368786432061632016188446807685910940321832572996649981481772252325191040086154426554657538458444535765717871033946613771702350305625265004320388243386097879262683082846870385959781954488956389970392578944288660459295031234507478736716881824136783622584535138805982288145285315709292044924680549217929790115984545014441521755735726306195457199770572691754663617787391418043564291295463544232345623814234091075245481655240617768194600801613370454579550360990469214942505585371933295794820730182459765487139302567668926438713305035074950095908181875721870629028442704188817930628082595769711646309710902713389577813924985084195489687602046619502008960961979336971200011845832972766496820425232309014424160383352549432587175804599513224295387620793237492133106194854781675335264245443368406349778626577154153936165795176414280246708209684255021094823421966794931258601926237888502063061179908920389122437280096694180318756729540187743522955287693403344627192008193243150047926683116206789808737520329932175926689631039801333205271773068694119886681439408208634536616162125484968246433299086618972038726320143524530159155122816067209479359158975104676175689942972909538981915518610438058966813454552135810617643268326508884740007563057812557756872119827948177012498720002846584320083602883505675223930415710240943383142087697091237570482781352256162809593048997307636369071690373544475334727722226964401838105804104033698859046508072636221121284767256179261384695575800126777871914608799740333135169078085040301870738700721986026518324144597854534393940110548874771456733548819690014891150299883374569036144504075650284247154291122602262577738634502394468066637260601515590412677997656372138988479892629787344855469625993188902215341743976591335786134612426484416557074485085137922648888557127618980204107341206517456111787177656668620397156874752365541689736459115633909848251703534756902949331850082296669410306980175719986482188446333446450823956158029544268395051423740042819986368612454904255206373684842598857136228239326853906860111911390847498545181350875035398066868621959973870036473108206470890805125591766035651660263166256071859066523494404932873989243033885387310363168734739688132495065765084286985470381074859852651721482664917019227944750044815550686001").unwrap());
567 assert_eq!(subfactorial(3500), Integer::from_str("87964690579311476903697952535762423171293573041549831274936832063230377496387961881818325071352362000126022647600219125671302009007771359686789512876254212531891950092753355796126046992513774857242432339339333447252782390365510514829896378091943331363298445226434169243647341041682693637335917283552025047705718743606179620237721970890403909827137815240107365022480391637222374108121610989139629430195740447594499162476924925761753896065968572455897006913141562929011308795335867966360121651137911521052895606137398154068818807527050702040952530158904764608197311241528896866121709121383604182201034765434742018825060316913243796781281776391694867036100295773369046670790385522751768636832092969508050108015738623884523245531324120166592130951369346913120217300513632695873818291127329035960771001998771206126436169206318142794123554007303866321668204237469209729131486662626246912565485170993538306414755056352947560851586773098953595642256313233249851379867036232442255598798461536754895744498876527681968761354354492707047576158302678895095224873599342851839817500887247380544700566649519276391975014368166344681311284691317802595922124458635093418346890412488353399986161511676807760260985582716782003108227290059624211491058442048370865657825059701419818090874444530701374111546561579906853579715976287845919061574251086979668208048769329795711131444085509117916969361052475322507621969047833839549195745407431764562643081820141462954616728643224174311951463115049364179678092979408523270388666724820774242348382042912267743010056997700031268389624352623296112305476625195636895577209727842898517396664307434638564583446052771848664649059251606564552198025097236159143436898622941491316116404027176288022394396660586264908732436100151684471984067779045661330652207815265549082928308925294739624045036557731562446095969313646788713297423629885992284846268942557929165945599793545941860308786165492769938736519597957349597769666061366120837416003934850618708189411098020107735661898987023479925076383048624977683033753070054859860275363003243244942946304343402379555825371040659106921107436910748777482289050509309926706331412950832857394161018706819894665606393858954099698056127800910399031861987913217488849867040052827141575981142204405211413582494654061270471036024734315935594278864231871024691039184822489106374619196954575870107827539914782731142220557019645062242623026221727309194863753886258573948257747513967037767828550744015732061727723268244729778736549758891049432907667569934141158501220497464926181928478953778307835953566247059496765940635380699983265826073949460771997208096870070336937598848179821051894439684705140849471755120072515257029959137778212800375460351018080073354920646370945741941634800154553888811450309234133504584449112307914779008369693230748531390331325895922551985794989379838622872524210467665435051783609604218458176648003274964146077707990975976236268280765140873260019036781201925125401480567049477443992146917663588390489638806499515406158460859565940934843640731634171429071834929638577410486879445333777436331724942319267885681588041957271116813751844518067954619461045274234671731629971934381930568474807059584442552526106416191776951215714071559066979314076869334695519171280451654010299961640187041103229115345161292553222755357135295815872391785443499846030813021312810702143146357073461137431823532988625245427436770117075095025760111649969810428473114214583666562993369630869575446589978517676701140858753060519736036788343419418617105185124121275438367345608695776395425137278057052289984442748338035729387341620787288371776819382730644633027274047771282773011047758941316074627464207424589638721993170932525856281376541646687545501022749130180523839559753006315695772045002882085473627587729530957335083580614897677969299970486149183518811846046910935519927488184484952509021797992421767912555572768013098629479426556070699241891692098894619448791303450217535578300653035214784304104612941484379436258939528989793337248229249876372532917829455089744055476064504661076615272923181881539937076670618926044766470319609981511398361154372412415754367903500461179995749430648049442897151777195861229513504655721164101719999476873679702522404923550850170049339063225647264431498628429379963108689944602674574530919309841717831276224289686829131766591678520371273662907809068291690255040203950742544662139963321733321885983378394593986216920855440540952425181171634296877940658670865280696076366370022234185846408478425682449402155035911713541542423531103734110905481570961308500547839824241854642339337746367121638802147086232742035082236149687293844035413508842200085456993102116390657292789376469986875266489936770793263235214678341519899131577345196917108210167938612105336141315492485647570337713582097330131071465133220821916649258316309256754483670844820463723841479928646014635282713587187360340335842916461041724879812062010034682791552016109952641678459959226724331046005384739690824171005092057197148939983215485933044021748741067066908330037346425053828727335790079526990685098335095440381806114648376891732360985954259866485232950768681143906797869488883362250628528117984224743776630068651153277921637952379690471297285066890575704551874506748076555958802924925596912828947483072312680055748721457158536611958298309979628268049779666027460243557939520330843403760671188346721303955140539101107990300377346632746731787751105097013010903507184907229126206513844656876918988795582127896303829530075104385732564924467829704790506109105834758126277618946388346004661311696310924958360270220105709679904356893289799630367572744438275175923269459162671177233194480142210788721530646823467125939215036536465157827413585445365165165915606415114099570094767091653632276504209889443402868353141534809861207103353943268313254640667985433420472553499232910442938942919693243233561177711979926110722172022737153307778869836921938587120527105650668696575824390138068745418782434841574997255995251572576406771823432674179335516601407313583265400052485324402417586844302231051681938575031066609247951503588903794036646174279702242564883441131160507126067243240092117029748077464903470387550328866739683428050951725595700639617287370731256213111999758359027455336528710956142573893881326878941093138131479379294251401417863619504206964901012032308773656436629188059311079457810781082974058106425244860363680240470052638940169307108921420711337115721225383754830003251702273619151233159279243133115154307608233845473881220670873291299290646293642508352998006307399916974568296893624787729206513193854404379855303422436094229561826000023221073445361466722049739856318354208605036699632697852644845119631570734162294941377191874106565985040658910112566448717064361618441271045302145484836205067631904046804475085968220553112907851498800492210003043273877419079679861285952923433908370629232474392928766290295064761239923630489630007957201301936166490884863426388521716380562674782761603792641656907964911228231491878619263605954533691517685422191131596474076843093189868252213720762798258300230150585792431906485315694669475768176831380871077799923078148316602418163689517261555968879487540775664659337492101741179114049283169582092914624642076458636012553193900023445784497194557250469946018709716607649225595788322693475009518057720896054150983017409308327434118273282094590984491205096140181011543655282964683506540015539106161536711490336637097766270141682461564210558251256707669449523336662127956338371056013133811171722912468083337681828360879384481805289584067164775747154834952255591004563041907301058117034926857977241751962919346515162869584710105588756103446049723659130603418505700829369029416617082551537771773315963730259239576084272960989430962441043516909431414119570867039902745353092903805511936260039242676378874630083076279075677001917984838363735263020251688601101593673204078661250191763468713933780382437772609593558323141361681098165177930721519667462360474607153307985411784774251110522086635432001126935882086991886786535526281052589277366716572437098827959739373617691344094645054981583127579297368870183680771108547000256373322517687463175442080190797890501784079340755252930289258180900130956090609840893843861202859488120034522865066096591692369186011865061204988448160851129870266754387045352779168322441197286011419200739289288148249792822232227137483483502226290940689315335190961838082107636284781807296530521465934474244209202411327384364890292342342239532860144004427078539453772671947862914778607665210576992750053067862595183262133101683685883334415755332658021542110066297060370283009577808870902943496372837782428630791577023804810253897055408079271452828274114865018535899788981714846791991166023512370519823365959750091304567581141773002573680791270530380559859697656309168340852099931237823578136765546626522053596853687797852320323209531454790757286059591405127963225761461430937644503881197794383308844051466772515323922349958895906460872308893973689678406231643106745061319874112715695932081311413162510500039609781053185701719167529775168703026564111775826284764297102288110450845573186849410216506710448304118878222539180022811951746668693251894604679547515577952811562942664145349165520086307524581236405990006095387226342060859784848774755471700187362813826753348876791437770855454853080145557331494488102984016740339639552706654048771346251491452300428733191430126465918026675281507907566035675129511981018241089508566445265211591578035818691584464421406675550327254285369980199379036245766621728300025441564224756866910745264422284823851865956822853013111521330386681428382313762390962977389059536522004826263597249812413344419449459395324859258294463308724554625049668243581592586787048285309221587057323482013091684826606030332563466378010160369982023106523146425596640899220564357825549457948129968594976767890706762981861211549601853515166568638120219269404031002591396999438558456268808654332325314025710852717882733843182532191935408235554135867539625834822279172079130605023250834063134900502356866437756782971255690075896572968873979658781461138828564190205495576680444062462826173866204657788879178818157997477375728407633299554737598010317740961150647865156603733581643099429387772620782425866820395007565203712773766894192129790362799137131843313622358198995613626445074121377413210616787069224579518600461499342184009844742205676798826151464786496774857532951680903713204512902906492992144576558538101814735471388282608668421110084724985292356091560524893629269178894789966556090098403458297809761629926668671323154980927956092141059964791488175259377863097489806495919876285801573446487427421624626193806177713467030192937556068993461876359185574959886193605006151120425325017505191363383024530204542925298739431122986169913687221517731141010893087148865761151847729898372580007271389208387839822814090101247615212567521751476371764734480122019911635481351322859718149348651001").unwrap());
568 assert_eq!(subfactorial(10000), Integer::from_str("10470804208445737513419697550328065766234399081684502763228668686283147925314523291314863732857026337680359333788520909830871014634592384682585292048843591651488378745429186959508254132734136717582691766695734308490073779346984573849186693486934977629545901730276260351384808998522474130864553928862785448752792107976590673721834208498342585926203001301530094295599095027796624265959994494831245191573138429154481209127194989500638951906688849372097945939546042812193464104539080530873197821078832846258439893651994841836130557888208557917480806961853235287156711293610130980405066995293756307549740598868239083804216287661575761990606362926425627694006133853650675293675412399201321126027742242408425710188498858353124206226685103346046812819385565110148001891982756945813847772777623970469392563078232299999340274111264366763599300718831358428923065215938745162710000988268691176446196011719661220770797592822093519250060403555953623946814614503488201400189701605013379064599828523666929213647892072402871979686494807552044228269648763949333918360957810138127763316737438698559369837240634716833290365568077088789893462721484938913233710243202470048377271762062789388943254993972375786908404156061280179172721981548789040600393178410172149490219974127200086797635214370678438162091745493239365354197089647279973252803829965642348308770277607999480656084271511088754078877478009920907972790643403112470506427875964328802646595496225121980604795110503058052652514680866929862334409587081263957642733467360261311791363211535232285904422509843325508016927153753313674093195650750624496765971145136947171849062536467139805955620769412300610603281876013488718989207907711003795320100917272143230335558203907274956697401964352032905611421017175724427425238357613918055064003946000491818751143095644265399718573230687714069993472666846569891357428592954364152580484792341251089495644960043895529170176893549443326849182733495831297051536241255935752653047696698903745391466909345830170669021627221098852675528887113411567918656661713714851794890437699860449797667911300260450883616779248716726810645040599089542481219168121165469725697055420024560361444987768415816264835422976629133369539531214627892728532200802257501640710835008000354025723491544005224295038359985260056411998117283569045028279523725371230387880455481160856539118017631103790860178134637032192259676999769105199569574974601729751224351343465417320638534180210038250318829483384956635179008610184779549282382841279563513818026949222904334033518362501369754827750481554933478395755351591229081165823297310518587704497148362315591637695524501928751651737536772211572123089245486838000305349781687431419501801222692051668217019197260918556086524288416706038727769240460830338943140354205217539019283325877642379174794774687568581098741671150661107383621181752233400175584478660588260442427462967997434861775384588313451660594239475876506001934006000447108969979627303843062370988854068560799623508310384376593408708742243022956923629025225916066758099205308116505347281492439914657720386252906588385796209744822533128427100396181812019701347081200855869274917569383875695993903779182634539676884500777202230236994218243629399712527313007589731305905080342970691632386032255332095994138379882631335566025764065386840065564251364379046258022478784016013064624502607520568701426656947996051104842229373414862021086934415126629746791526412715451600559697018574872718423429069947207433520729788714371823549267220241962534655306740241818325099137325595378071306772474835674494707184516232154878647653255600872740039052330521325769422505536782904346551645971669399363470121582924022729960562297642564889648410830451616444307241473019675494571519842112267296059719024680715546156208292144878997457088622307843887675347512009263451957942516024144428454580661665177564235079872350203976163545684058958984927463303888578509139963968557749867278601022816458931952934489554559979794310156756344343636887852030645117871235511211533693431768762022101161420785380754040694041326767751659471700744078805008402066924211790063735895465435242275856339436923766706119970913618736852398490089997888528271626638206505577570308765334389747342861326937988744110214232627672177017452607978732954780650459256401803914601083012676954709452565804043303302063846670940664281757405513090738277822636702893324327250764950690381056508195912604968777909113401326506960972955300935716104795842686555437443301499088163322897146942231277746474407947711594885853922040651598029478653371032034873824106011431812076838503512508299585553751099350917559428969269974525426809897160661478807729052307941319321553275435141562910023804182652470422508181053026886165461526208726648451711411270388334176099847283795510461878499537951076487290508250153934165372585528652014483769152277161686953526948667184093854496266957530311775595193814819838920043295446215644096431815128614604364132186241111887202953138123079664535661737311666445626059217701626106297061545397357774936229199651729032036540169655133823191976285671135294163776673147525001703519538467777433996642937341187124805038554005264208472561321250547599670000316481245908269626747900226615912419764764802649875689440094096870779955821473548372510891906607332803404638024808036060505750480491974074188817660940683042019559433884712760674251622760544800282652772709807325862294709922251378774517065141816863032846900043849423479590675161013626998803617790719652567349178635349249673549231936422641178035822810719547641118771722099373837874296804893895077340147562154003040013578026286901515160311623640809709836788767865912615870756562050156774182679805113623153889333325635517119131042345594595690704651760028610078443650183490217915939367916990660454222206486218049916829763542979453310478092780154853562658148660929135297539282333653790081725296488860154171078750748341136549245525364241200187230924947697033535777586553738878650519271231267046962654601810437320606437775770128946464167224848885592616619129412492159830241722159644968367900935047553252580065193774986877682063058146597770289419781319298875148452206437502521859974117081363335803377304356844475071668323080221904315595210095159961260265123153864884214990249612992494062492357764540382458605173709756108833671698924720650665709346373598613388402672842677033572418866312374221375979516452246266386150714199136589299429068974357014503721467541706623048182616094974959703710017987022778996036186738690343831546238666916722866159687599074384158251782818170165357244779964257231498273594914189015508002805585315142563894193110988707816223659650735088739913014910174553129522208104659335640480459238527154812164580455902045680673724918458655678621266030083426221697732870542363455606128862925257453435423971309170659876883343414736683467620247869427930582431138057069163855896539780424613094508906952605077800017441046084168571716633056067069276504441416543486093772915271673165386311881456267488375484682749843821543232295618774961313542118455519902990566167688910014187148040191674641135373610751817391519699884491698261243570898820063868684718312198422524834089184168756904503747578950705409840778131231916024025834927205557321645332191137252443613743280334289419099617442265080768250112756858074782679506896546630835865927212449974669858333314663973598869878383453152057951647297054761497166125559737899928832594757891195304034155362881121423079731748042663525360110635647778384891684192190162159675968459357399719407442253242985776172857047089216993666255799713152360984614008679140552449232203700435817923730831313779660190627759659410700384562947772146050960139093828930676916831922559549938467206820043170047455612499380530297303780587759817849307320401403667095796791958353310637574587899422852495136727167734750728032516229309482604755361308965243668928478232859821334880102805160257051722573558291906212230475424451475887650393245766690616006878839356263439625973808491327497566220923272121975065282806179537147166487589409173669735536494512339086776965172439730632769542720438983432076346004493716649088656518840569139408110124831174259882495932099263145834903590117428647512124184610522409437785376287182098827279464182984376240364260950088269693633930944218689607660566083060519610917000914382398817899959982682059468756179218159283618178689620064398017744357276218891288511295019058523707852542041994624475948910241164874446340922605961277294560816033885330083484338061754827136005648614311838883177794744421429437575107427759860720771959007488223069488094815681375003772765517042024067132170237355282792938460828563226527181110430638670220809030535736070065574462128229609484906993921043303601955031466064248566108709424703598630906451254942954594344036293038650933704474029415230217770279534360738807064394313730180910866745176408790616543314797978631594644204301204244929700208992849483393791712171299743471434273404250575059383862166275628210256867174223733501739358022975810340584079248153974005442782771754468623377697809513269757673748433841725671363890968121960227164777270535863346228560693039222820912336290754334665522387954448946387261326581898864931355729356766513242362450515796757963176001098659009338192332210492438807857119228264251235881920578675941372359527173549096428833358895427008075676651500662441685480201794772090607351953854644224601057787473724220439694396562270625047816803609837035995923691683626333226367021675080033077082419536304786160004642147768499150675695833309428734951549164091518000324740225776840825642372662373977428749387986492812858037668798036002929788056338947544700879134917962747795438084331458998311010522893986187914105926775514673229827053829624852732346463184776622392923307148006459748450939409716543500363905826461942526122725135256169657138658693560882462733953572197490397641963059239837400921779278370052600553910803156792213615983745447952033298155519189465020996552731940778352496894136245963547452682782053087192574854776019151301468421473114329640290019790492138462226041908293503795907564438847431249381550813811800309180797650285655530454868162708096689899448257552199366572239936149836919157780088989230959613725941672791060749711554226371728488900437937984927196797643293873761148405527516380046543252492883071614533215209066460610249302455903802289204356408602745618272323178338875142890281253915815530684387957940480204268493720627420568509282624818126433208713995574029733653900267546224689867784009829331734475363813458773591008635906628373643497574716315260886476178278277125932768149294339954859664837040278806123054846637193264781044719890046280412984415392836357144282637357120418378946746721368101876804984521230416244134971570926922819910788994326293615177812662689093761247633456281281713365711666332978776299858847574168263496339461321277062402977183768489139775408469658660855517239906285258981479058899282878924875016723303064571666748623703124356379719261123338924304084333762690804030983004188733758405265004800791601730870201446930815458304483646031394824798271362085110005966219265675927459001434832094005932884367732115596152271967758568362453343277642347199897918387766814706467599271211659554026636350408049091482115738787045275868753191917756210674551993832702780915571774088269462165398467212464550309684955437776251986784056812194692977570336240674925025448673455214339759773167335371101429321131393843706476728657007910190971899243909830430601515391652980780967282011622721271612339229825511999486969560269491400589672542812472160557663893378893620448796488304952784250346246933545185551410452357588262241777965639291585910286364695558245980673011757727314917325271409268929217449541885767036611503808288811548728556269253380337327959496571730988702260550725053462519221480037545153213136967682460202580659343277832539484921396025112138918858539731569409297154924193273452847683547077134429560186399185444572771094255505711820711809127743018342601913797737614626719603019685411005612856253595408163021877475450077572075100221620062978561338930288641994014355610095243132126598486696396178302000399524720396079218852311798128036483597924128365413619115488585665514789760816687634499597814556807603530105368332517459600965422172226569724934083282470755418375592127738146133018074399861487418163021793072457932717758432092115166563363561458755473762974086726182234604174740844779988780692518970999400680051047506986380519351516979663386795659047211085641745731411422805452693725431533707149166116623497228761881366370870268452756329824816208422302587092659669043073452273657513588155241520242717963852101033722211162579247751810411015261706360895158574149181164748103496845798023345617762596636264324794657869535392107596816249447139202763324739963931956685830691420520791176509073720984273140732275650714837163422426779360863540660395868779228343156304015202372081012971821691956620118423564707373856445621139377551362652704644769819385822045936585792027015280866431812159284970172378844457509860963930751205247508683755489809565625778666743363253412075173108925721294476043164696485747537925072884200117807458175694406257462846932670846600766332192644366346387339849586500904140724376615018371683322095759765307582731074430763408926722525189261910986799889851952217841805239743346477394077393159576502869501981680281277334604246592028613480648131157146587278576110499541057370729118293514666828334082528080724702095848455372750832388539070283263443600155790579255023901713489839448327223891514375453546156678872664418296743999047486515149641038541115992001659877388560970291946776238653365522070881765925467185174514655733645962063302213159294686520592875954699404533881414879356980705283921464842127041939036174575434398780355679345324939994047195297843863119026324295878526072217105547700715315144010538637158080555089547660946378854891108017440653418201012956389621697461367420206341094791972852230649491494324063295934980444147996026373626112726905303792612309263569848767385162973803150324498238213776959041298152400852478772873779525133255726018906072245877251038831206287991907464187041302831975285773993099706755111066556828048122338995340726307961615444297227996738329184948356047573064521199233027737021878906776723367170547484980189711431228166697291710254543514083642340264684832237945373491586213685577868306951837379925299239460564579755803766467017738249555400592370525872445290389790320551312348435518141500399458734890688783954218109888723602747397854694775539226157286325126107548367823446179120805965696532287620331852533718175632217151290050910909494063817890671316778992530420569976917442727887537994681325103731148764861565509598187550135040090421876905969936376257756343739796541698771908414904108370552366607182377065007898761625129009037598395250361669747487857031931407273669825835272242606123225859179185181191117253775042309287364950302099650511345450179743955377122950270463476272657069220267228817614547751194605858950316312068342839314623204820511938880737045337574800494906970528834031996940605840995166143314825939459768300874879987913557609280237180980039388757051365384605314913437885636372701063341483097457800645520849599582055917655634386114112999827000311821927848954234161626253302866217046494086051035155242164267301234694802327134854312408826632578592744698222980566680267306271151350532030199870320094429726865617749926605641477176076499378221254759456972878979822307626432914234950628859358738044645114532948142689723317554632344894792742183713023141984258099995716381450935117944859987547683165612491255316816103704911828184194892477896109739682474343417527220226485007332716864342023707217573791963152388316123138901077586530384563136722954512972731860501229346896069740093661737567301134957764885309394376940063719710587485148176192281779262337406068000356376648018804989588256371199994698085291089388748515167522769306088273081927816165694727570786076966418092611799937893104349877073864105566832518811342209758966723553585442246361058011624762127164691760603758088718733718842479918000986125877058882875792552236938780722021377155789918018308376138959857320027760323084732781668849142214837568397649277751035784737167861401626219518954092690083091596125567854962221850424293665561196063810573548601439753226015668289139703362037528491833039699227157423676197255442734679220062222671696232130751652801340911577342850980834586030482855635960556056236841928630834259296729636439259196027590339032323606613813093205098911331867547802920651761880077232392816695021870289682810721036848809838002989118228284980185155048329898410931748715651136653801765406219511236884939664240684734143118235633830467384704187829036837649726222510240819836519162968647759493982314193929751250378813294804838087818648041905239867471108826029782357138577223446379924971164658790708640549528292047360430917882210670031911057774209297368479381050855893232994036974979223746285937164804561100829581985894457419543977267430329166454639893828034743854896296007179813691746293424232622380779097953304267217088020196608903911231916164220346650702957007827689322348171265120382840304986736875058942087845791604810961746587970155242520040179330542708791616829428814022146073913361574301248156042304759943079873097045727584008561329548390011912925241369660895950201960941597784579441137492861345272061707562329263990536328273448283792000891598381302226144183170417583595743796158201903037829065493829911870964565647487389529739501794916885184780727957831764981996698490290598000245114278784803047404582518052859473903725617314005792329343802512850059919687362848880601332057248426092883843183010420894961268251790512807276480783470388600253023342800002304703571914779308421231376950892275468716507972092349840846812337778408832463997322196336219761048147290510699947982916022039008617147913599155685877313070543477703363750785834856390416909626866103653808828839602628140324799690035491663055446540173397077823041882874002320825055790386961386830765570739087579219901788985353593416974599191410014353239435572647122310036279383987351226409368956533308413418399098577011325248621191040845997260791124982047332304525684764911904687560224886975499231171489760060657571756488044872698674938072833832815955945506517999379515844581007675800467704175488209396446538954750365631702915336811594147785152958493122663318937333460085910379953151337226931233034136592464738258831477535933286461728620284752210526966726943540329166518809787617489867706763428205542760417783701482268886666587434849651682335290602797879326966947923753856753954582989892569493060524211198936037540996476144283090016406501691351610369421622265971913256587646416765381070281609457883766583501175286244280433586733196321109000402816233771494621921745060701983771372901077527185323374899300037723789756395336953308652589874151257272587987486501254993664063661283858732438979988607952882024898826064624574335403793020971291464014762104982555216821369023600693759883159766498743559888128709145080397504422451994451273434933910964249027488220507844938801884504904386121142272951354338665370625024266813175265229834709077056492774682318719867401242211217053769422656544738206563049607956202619561653581134046530242203408982177033031756449491492720298370590295196431823391458600493196203582841811533575746824484786633632232059087579849598344841639854168367215055766219768649438973084866226872641706285164942477199614714541275663909682125383651353521952139764515088027704409792771539839013538030080565519127297284941158819784323706998789527051373497418986794194804088750817305716846965087804935815333537721016061797939163127513399950437187016471964699713745142557614057824414132635689139352094545222705876950825662108973723863620503039232319469905029853718855449240771801339501191488777470183563054571260676668262012860789708052885037163088777825366606215497769932717209011066386375051919140102564166017777337330245568615664808541942334875329174299509945658186229177246312349587702833497121049144761808555673059709965298938376722602933535852894057058739513392151629638781171483779924123985080360001218702725389203102300751123738801511846102653615549900245740719572512213915275085567631719046857275716145170207766449824850169187044246637684225291818209387702135494619468586409387419060297227191493319591037057891634377911935514443086858270056798790812862914874477064096203239888876474342281750952680538940505433112075930728150593348635525487777442963225326289120005105942009379392399549768222904714335587064965943025883665161298876255240853799813319173541181397920169431341225855464506094308431894355976456616552243350757295794274103766488587493403745572938023109847623467233499594760052941076253544804607600806063492315687419590824313035155495322099282602206575716795686579274404530700878310553860840075533978970313868303268348968123830261107378525434730476155224319783326457731179933403040373373513663409359939556713528784760662130976010031445893240306115071698977633370081285021996081889866339554439030258689926816839459672349572981894713132669503720080825550314634827974834111135884327479840874856406704989600384782896014126394900096316936191822061604501251999538344900075456781099804476987941975749466091947916959084522070649368611024859576617679719912273442154392834558334485913297306149687463050858300178589163647727264373616866934235698778375400684831818105359191807090147530722705717027718640146392024267134962534073989786676885904328529992088901061477810844396953510495214390524762275536691861895423586264465164725740348030841559394619283212590085139714355818004331507117086865037471698474681961819268100298082475664418905351845646033186826702738190904752418448024312122874238653934017086873374556463443645085632505731346752773227640998162989971115011361849940254671486438090582719295319889678616480620657813783138224459920080909731816532435555059792303460051710222043788364485705803898922576121691786795769314871145350585237724501072510832249570059794020119350643510305688568246082138494920459453811812581825736849524777703220341825744979233777139161152867568397785641963636669540758862735103120386388954775830331682383170875177539060717378521153720999893078493738144598688821475846843537696741577274782076483996232679823975388834591135615695494497619841829196281769585395730856015357146391920884962079419788849671641593481052050858710399263519566383349271005947865683425462712430893507169269608487220667193961365500208793718669532672782433859614217392866701136490320043936895463681443550084616585257282179705882681426252239806728153122577322523327938614442576466221682889501747578160491590888486986413952574574417981777668428162319745575688857063620009672969964906294132424597878413674782384355992292957599025606272133217638318467921927254853725179624905946654971750248321718919983352554139549960613440945135063912560448331100229095455459868779391498683820423958166072743995598190911920585944019297389754958734961703000839661563087206444223638379252099015274749502115873742073269764203776964296057528352381794613150551737665105856274242718076573793899323417606096539619015279321213731467752665656665563262648200304204650779359810654065948808024247440092068079186241284126574359983902720032777339632477025162655404597530346242813174477583419225166728353026302670093240319294012281236946269041889392699809915794650841899872777464974521350123638079156477221164102550780694318110264365742612140703581132958639748389286696158157101918872246915899757974446368051307915707695178031057812180446808604258885258957502474048267815718369842503522659004754833798095789660916425455565990380991332902234007951931388391969465358626614736267112951367436937397323278176669260656847908458434257592787928921350031532312298293147204602982517875715301803422814972177220808817322728517063590028270807420546881710724894028229355135387259801435676527204916995565664049037929909899806932636810603860026476225075911244308932907821666690512655315131809317268282788637121740948256128007237130128275345653111893740753660953615156706961863983815828043076987086619917404521350508481525971244475840886105350424062492056983002524347066028789924820302354525617169585818271476045073801729294906399100444971566147560806094353685649968843289464395074043266462835570320225427620318439203836843781986815254869839478423063207607950575995797068006265411925792137097671558992165741166579806000823406002348927039276640883619196770138718620522358389403691812979046572135592699639665699565160272535288210179012315864025448352476162477980599847927834499817197182557732085388517809025485001746194188221500219729084713772439508357060846413203229354597109403144097046076106777627074615753206039514145099843069544849907261285374315521884205094839140077972052113910827700433833533195095289050030294256170489553443994111098268561032914807626322859352968954864624163264797120940408256574139730558579817592795684579438059220658895058041261695610070963907309083666004439202504322139014462699084814011176672110434345588598156748048117460923964382157747811149329705621520605486817468160076811391614113105794003617852541517200552077964551044754791847748054227907360598462456043406019493357667165955562926631792324350764081020489540627309119524703617586369707304815238370306308759632566956470290404936402049307854833321916357103544949299888067390298592507395901401441502542841938592559349497396214323731857557713305074567522366954657961936003512614522765507165626460919754145222041018228897254305726755428439389964453623380276774365218774539032393211163180834098215060648378716911568535740816976293148821572389780196770695202697003765056785071850033331273322015268099191299409061810263666149225513799905741479593420601854582820063321245261325008506832047328279230239895152945020063451638105810941102239536156290437878018245339806504994293906452955120444261885741882061731036442553358864706558163689369851297647325533594481086232464648030351316985095761294514040778603364410944828292472741221382736342742756006421014723581272582446712591180242335069384282988637703230238721301206701058421558702079650096771934426949772668550906655077064126007124879048779692651159626267887153103989087015621234810889476653679401501072304356090887981283160917876677210369519273529322623887080831983181918841137904043243409988480250085922793448986468738365936679417026102875460159987194566165470416808255718158250643035430102244076907735762508373942459764672386109089689892414160826570705396313057031967913834700469093586360166251234710179642805886327558510655653942850643467077146599446616384899847125627879899301234865243143627438171700746460808532039052870054242884593575882889607833889457727580760142131225453842753868968819796062311706638373745389766978772920651890261300367001668147716249037758503300878223042572801391341555905355459249704629195525911947584581014131812022033833116089251629389123769176947301494827730836780968354751066449063737025479074074245856157821593924037392070850810032699400228082009328323231154189214275133513018970997849560488937871683531281338761559984889674194173148231882330832600483976903999007546002498462597464299971040955904972020017958705024723522441387421870472997388097191293448377911973265241173534257086399454324450485089946294663046477667154441805236317818458906629516169208154526151315617330670283223218993091900911765682141730466091313452218042531797723946292358955418951289110906622091567226488055045979246380762361941436514821475222262512680337778902784842389712032032130084017679701773886952203168257322864970051809257340534140265340200866802112386503407620820264688667366957282116700299653886224110191383006293259473815849306533516420046463767221456140174501544468412399409875186524218934915438003721881045821282703695252798667918656886609245099391504125431711846592149184051817465437349977174347837606342760204652088659164519539922168629606647891302584313333437561767097111434016423162643732303555217933863437776784586509910921216797793093304330231034562622395264009404026855934414285180439964826510838242640371415473486249048729519858741002205884017462988017928172952645887687784314388566048087532515201377819448609142557022770281845499435897397281102140095532371776104076975732393045106245693068996512823173232489771857906986985204778673860364231244043612467408169586743226755522055777584290442703332547583332732967539508392379151251321124704491640230355857776539611337747118874218276417528225889674707284885735356358382854200935084500745010833537679268995256161120875502448514567760351387650311731287040101064712539560262530297789672721086032881550616445083241975850148461266940099398925243382131479074052311643785629349349880883900832357058608177198562045001265455158322670854789245768692247464561027993647527164672568939500013444099092189846238207412425584187502950907741807785297907295647474777842348427192411545174615971256410794586811930576920597061283872380688225040931478778844020901470946467312081133168383151995754191710819056338637795809958635796220949489786910647430131255248202082854990010963954915193148727218306105613718402254220252120966462962463276648846953811793913954119951607653290213646590366257862538126290875136128539132829274729123300670065575643732429949108873614165185893325426741854073363226249692874485150925886864130547106881249890867267498019733417458259885949020362765524694742412144456254270044159576397383977902083490960194766511852529279622877032324846136135703995030201160350261640251358015958859079290501427051917053220092317924591467349957486672816970367146281626571039631839017196390467313370078725735613114129599537865596428324977661784861101087632613962743201206743346610160974347425620162114921023690344574221474983119943114407206893107461402235276756247259833002706319719088651822495170773670101048510985648393283651280031657365265668206594927455951998307908821384284578377786987830102020407192211890338029704955782314718971341677121917654728886960073281135057236117551596007829291384717912022425858119805221912896124810881753204662239669935353419459999008531250745154889933444822638878124608978432471852854623282403280920181481186464310792655039504154593225406285433355623610861835852107682352875496220312435855448925363298214142647974637259090049401236137298275444870575949791750744411457589313632569792802726058546026593513791944965772645398373453284070590856126558837292055546988436660443564983511472430877083527754906745260731762414650843380006266310470712004781161897897983562336143779820591891375214738147796050153044109677157374732113871428801990290704386758852511753497780559721643875320740234107435351389002122886562278711700400998034025420496659471509050546405003810900479545359277796814742422888166411785591096780582395263750564539544648991518360267309909793899802295658384215335624896772299185838588471595721894064341817922979846887606306363202934778363118638607195732210319573692213320226496212377097232776650280948653029712615343062182437706434492764120595897200779999780868894812718948887128501298956774390296751240376170729454946365759048694518270378730264607614471972985991149551940402652477921927044089937950348975699766032253467964963737678221848200983819412892148330385997139587788295876113804291626359032297511319134899061087376259605564672155914921802313771988654778693375972879181050132446523746060449231993904233982672262835153220072712109290775578271228853364184185228698342485321632136502937549482654279517678052996050785243384384058128780420660529253115640056282090940037042135483376886732494354664928950500878867031579320450414382992620009252978018553646568000962682388709432035209782586463767979368992024543452334855686772326356983596758925801126535416178710682880074666000622193730746818392066059256325819081690408769018168017173064110788053139886769597301683514564798990205810253947331763155781800208086924188690932284987947630392059596888534627059112301771760501487361458521987196213591855744144613616302585063419358325651139947839321964023493397425927178172848197915030663878665557892938749011612605284649464267004525652064304741934191644127769757359217920235087660873154796569350159265387172420905034663776646500958039664986193224765031663610953836459399080886452351477709273172155363796168648962409233752840696835447043851832483645383284548249948048507276208964256777184422574004963052989715081256327376718992437219942297671010004924320058004897484941275968437270536703157455329406363805822341831237917998873175813772145577116894769354547761401461155314249393178873456519975392121918019012831439405169113792038871988339492614357476912228217660535702146783049238999365845994575191094951906196379740519757090907804226553443599071553295378092984118203113032396541138588441038826629293694077894093015806320724193918502876739928855275221924314853301197933748392413352237681326865802135963339166417905037052807049658315100181874653664359831865934884969520601418977194151998242549054131632967122552724854869127759759634291858587983843705499811769987117567468687946038714975392564315003961838292191737956854765660172117108728297508105641492940809020929325666817806570006830692366760736425478289110751151782561008808977146996309744817294166513273638069988920283912595811449273074248519927565105178767834291852674929468558435489239974000862490414944937456643825941231672457623789548791378557960240551917898552708591002918250529601549989541849633919157655470608074666270535483794207125576285415223668173099762278406527318388201878640424556621653721019266410843331116329388659400568962882971082297331707823855230753956073037891910721750189880384013187346223372171098013621513884886508862429098931596287249921691399542732147012069775511068713146346520256362219959105914129473554905496655303859983691769785915436781746168690034710919369005590137970947358525369855659305331970094684472321122713072727550846610760770599690497959338314058037155309683378375263488274716507235493595329132691627180116503218155620267384747321312021432845876715701713708982232692834099148408860495140307534840758730328590908191410138953864509819255932336894201926818088554661558271492593039551678828091962105082644480974005499881334590682565442542251470440607391935005716756962969633396116680693840548065797448446191814107477730444383216910054354698420964162392835082489955747930497798810371744180848476136862551414125951348575757687024835027211380965422039072283636251413370710568492499449854565225776485666139900068764217000475005875487362029073322005180003839476317508324140165184626463378265344239891535609714966252524456542011112110268517384646038893930789182908202749173592508621521965900014603594125261572859175616043119293876481256072942355007918872108162926697168795532222265305459300668777886829315743812016199414387246146683517071886869678074958527306200955866533501217590227882953219735671906412160421559502336345619794621582753801156419042014314756642399090473599915500084217999604434277409457751863380315517962339407696607173148422379600729174630189562956213451379531368453527794205273942534410801452384204033170245702779681536228618272373239264244598120007230512276293104523529217928549077467552158120984625533516460163222926068748233473110966560180056702595162762215914091365195281331960134081407474109223336704920381376694266546564087520457945062098409146620693074310679187424255721361516614781361194016624696895842695903803343579910106063298889692578541626802346560583100633747354337407934313565705254519304973967146885442085857802708776383358276365405086853295174806607132271222643953230617934451814439436185047484901159323083380287884219035205579366934892797076911345721526124885797554648608556958007202098342427437432519797256899166093398874274460025233125486206529441200438687836975825643669634856696299955576117061673759191975358200811003771452160907340515326715482086200007493660885883881039539696860001").unwrap());
569 let hundred_thousand_digits = subfactorial(25_206);
570 assert_eq!(length(&hundred_thousand_digits, FLOAT_PRECISION), 100_000);
571 }
572
573 #[test]
574 fn test_calculate_termial() {
575 assert_eq!(termial(0.into()), Integer::from(0));
576 assert_eq!(termial(1.into()), Integer::from(1));
577 assert_eq!(termial(2.into()), Integer::from(3));
578 assert_eq!(termial(3.into()), Integer::from(6));
579 assert_eq!(termial(4.into()), Integer::from(10));
580 assert_eq!(termial(5.into()), Integer::from(15));
581 assert_eq!(termial(6.into()), Integer::from(21));
582 assert_eq!(termial(7.into()), Integer::from(28));
583 assert_eq!(termial(8.into()), Integer::from(36));
584 assert_eq!(termial(9.into()), Integer::from(45));
585 assert_eq!(termial(10.into()), Integer::from(55));
586 assert_eq!(
587 termial(9572950215078573219358678320u128.into()),
588 Integer::from_str("45820687910186450629655988665746507398291523758298350360").unwrap()
589 );
590 assert_eq!(
591 termial(Integer::from_str(&"9".repeat(10000)).unwrap()),
592 Integer::from_str("49999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999995000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000").unwrap()
593 );
594 }
595 #[test]
596 fn test_calculate_multitermial() {
597 assert_eq!(multitermial(0.into(), 2), Integer::from(0));
598 assert_eq!(multitermial(1.into(), 2), Integer::from(1));
599 assert_eq!(multitermial(2.into(), 2), Integer::from(2));
600 assert_eq!(multitermial(3.into(), 2), Integer::from(4));
601 assert_eq!(multitermial(4.into(), 2), Integer::from(6));
602 assert_eq!(multitermial(5.into(), 2), Integer::from(9));
603 assert_eq!(multitermial(6.into(), 2), Integer::from(12));
604 assert_eq!(multitermial(7.into(), 2), Integer::from(16));
605 assert_eq!(multitermial(8.into(), 2), Integer::from(20));
606 assert_eq!(multitermial(9.into(), 2), Integer::from(25));
607 assert_eq!(multitermial(10.into(), 2), Integer::from(30));
608 assert_eq!(
609 multitermial(9572950215078573219358678320u128.into(), 2),
610 Integer::from_str("22910343955093225314827994335266491252915405183988844760").unwrap()
611 );
612 assert_eq!(multitermial(1000.into(), 2), Integer::from(250500));
613 assert_eq!(multitermial(1000.into(), 3), Integer::from(167167));
614 assert_eq!(multitermial(1000.into(), 5), Integer::from(100500));
615 assert_eq!(multitermial(1000.into(), 10), Integer::from(50500));
616 assert_eq!(multitermial(1000.into(), 100), Integer::from(5500));
617 assert_eq!(multitermial(1000.into(), 500), Integer::from(1500));
618 }
619
620 #[test]
621 fn test_fractional_factorial() {
622 assert_eq!(
623 fractional_factorial(Float::with_val(FLOAT_PRECISION, 0.0)).to_f64(),
624 1.0
625 );
626 assert_eq!(
627 fractional_factorial(Float::with_val(FLOAT_PRECISION, 0.000001)).to_f64(),
628 0.9999994227853242
629 );
630 assert_eq!(
631 fractional_factorial(Float::with_val(FLOAT_PRECISION, 0.1)).to_f64(),
632 0.9513507698668732
633 );
634 assert_eq!(
635 fractional_factorial(Float::with_val(FLOAT_PRECISION, 15.389)).to_f64(),
636 3816538254129.559 );
638 assert_eq!(
639 fractional_factorial(Float::with_val(FLOAT_PRECISION, 170.624376)).to_f64(),
640 1.7976842943982611e308 );
642 }
643 #[test]
644 #[ignore = "future improvement"]
645 fn test_fractional_factorial_perfect() {
646 assert_eq!(
647 fractional_factorial(Float::with_val(FLOAT_PRECISION, 0.0)).to_f64(),
648 1.0
649 );
650 assert_eq!(
651 fractional_factorial(Float::with_val(FLOAT_PRECISION, 0.000001)).to_f64(),
652 0.9999994227853242
653 );
654 assert_eq!(
655 fractional_factorial(Float::with_val(FLOAT_PRECISION, 0.1)).to_f64(),
656 0.9513507698668732
657 );
658 assert_eq!(
659 fractional_factorial(Float::with_val(FLOAT_PRECISION, 15.389)).to_f64(),
660 3816538254129.566
661 );
662 assert_eq!(
663 fractional_factorial(Float::with_val(FLOAT_PRECISION, 170.624376)).to_f64(),
664 1.7976842943981478e308
665 );
666 }
667
668 #[test]
669 fn test_fractional_multifactorial() {
670 assert_eq!(
671 fractional_multifactorial(Float::with_val(FLOAT_PRECISION, 0.0), 1).to_f64(),
672 1.0
673 );
674 assert_eq!(
675 fractional_multifactorial(Float::with_val(FLOAT_PRECISION, 0.000001), 1).to_f64(),
676 0.9999994227853242
677 );
678 assert_eq!(
679 fractional_multifactorial(Float::with_val(FLOAT_PRECISION, 0.1), 1).to_f64(),
680 0.9513507698668732
681 );
682 assert_eq!(
683 fractional_multifactorial(Float::with_val(FLOAT_PRECISION, 15.389), 1).to_f64(),
684 3816538254129.559 );
686 assert_eq!(
687 fractional_multifactorial(Float::with_val(FLOAT_PRECISION, 170.624376), 1).to_f64(),
688 1.7976842943982611e308 );
690 assert_eq!(
691 fractional_multifactorial(Float::with_val(FLOAT_PRECISION, 0.0), 2).to_f64(),
692 1.0
693 );
694 assert_eq!(
695 fractional_multifactorial(Float::with_val(FLOAT_PRECISION, 0.000001), 2).to_f64(),
696 1.000000057965408
697 );
698 assert_eq!(
699 fractional_multifactorial(Float::with_val(FLOAT_PRECISION, 0.1), 2).to_f64(),
700 1.0022813772211305 );
702 assert_eq!(
703 fractional_multifactorial(Float::with_val(FLOAT_PRECISION, 15.389), 2).to_f64(),
704 3753266.6800373434 );
706 assert_eq!(
707 fractional_multifactorial(Float::with_val(FLOAT_PRECISION, 170.624376), 2).to_f64(),
708 4.645270661441449e154 );
710 assert_eq!(
711 fractional_multifactorial(Float::with_val(FLOAT_PRECISION, 170), 5).to_f64(),
712 1.7184810657031144e62
713 );
714 assert_eq!(
715 fractional_multifactorial(Float::with_val(FLOAT_PRECISION, 2.6), 5).to_f64(),
716 2.4698196281039353
717 );
718 assert_eq!(
719 fractional_multifactorial(Float::with_val(FLOAT_PRECISION, 170), 50).to_f64(),
720 28560000.0
721 );
722 assert_eq!(
723 fractional_multifactorial(Float::with_val(FLOAT_PRECISION, 170), 100).to_f64(),
724 11900.0
725 );
726 }
727 #[test]
728 #[ignore = "future_improvement"]
729 fn test_fractional_multifactorial_perfect() {
730 assert_eq!(
731 fractional_multifactorial(Float::with_val(FLOAT_PRECISION, 0.0), 1).to_f64(),
732 1.0
733 );
734 assert_eq!(
735 fractional_multifactorial(Float::with_val(FLOAT_PRECISION, 0.000001), 1).to_f64(),
736 0.9999994227853242
737 );
738 assert_eq!(
739 fractional_multifactorial(Float::with_val(FLOAT_PRECISION, 0.1), 1).to_f64(),
740 0.9513507698668732
741 );
742 assert_eq!(
743 fractional_multifactorial(Float::with_val(FLOAT_PRECISION, 15.389), 1).to_f64(),
744 3816538254129.566
745 );
746 assert_eq!(
747 fractional_multifactorial(Float::with_val(FLOAT_PRECISION, 170.624376), 1).to_f64(),
748 1.7976842943981478e308
749 );
750 assert_eq!(
751 fractional_multifactorial(Float::with_val(FLOAT_PRECISION, 0.0), 2).to_f64(),
752 1.0
753 );
754 assert_eq!(
755 fractional_multifactorial(Float::with_val(FLOAT_PRECISION, 0.000001), 2).to_f64(),
756 1.000000057965408
757 );
758 assert_eq!(
759 fractional_multifactorial(Float::with_val(FLOAT_PRECISION, 0.1), 2).to_f64(),
760 1.0022813772211306
761 );
762 assert_eq!(
763 fractional_multifactorial(Float::with_val(FLOAT_PRECISION, 15.389), 2).to_f64(),
764 3753266.6800373477
765 );
766 assert_eq!(
767 fractional_multifactorial(Float::with_val(FLOAT_PRECISION, 170.624376), 2).to_f64(),
768 4.645270661441321e154
769 );
770 assert_eq!(
771 fractional_multifactorial(Float::with_val(FLOAT_PRECISION, 170), 5).to_f64(),
772 1.7184810657031144e62
773 );
774 assert_eq!(
775 fractional_multifactorial(Float::with_val(FLOAT_PRECISION, 2.6), 5).to_f64(),
776 2.4698196281039353
777 );
778 assert_eq!(
779 fractional_multifactorial(Float::with_val(FLOAT_PRECISION, 170), 50).to_f64(),
780 28560000.0
781 );
782 assert_eq!(
783 fractional_multifactorial(Float::with_val(FLOAT_PRECISION, 170), 100).to_f64(),
784 11900.0
785 );
786 }
787
788 #[test]
789 fn test_fractional_termial() {
790 assert_eq!(
791 fractional_termial(Float::with_val(FLOAT_PRECISION, 0.0)).to_f64(),
792 0.0
793 );
794 assert_eq!(
795 fractional_termial(Float::with_val(FLOAT_PRECISION, 0.000001)).to_f64(),
796 5.000005e-7
797 );
798 assert_eq!(
799 fractional_termial(Float::with_val(FLOAT_PRECISION, 0.1)).to_f64(),
800 0.055
801 );
802 assert_eq!(
803 fractional_termial(Float::with_val(FLOAT_PRECISION, 15.389)).to_f64(),
804 126.1051605
805 );
806 assert_eq!(
807 fractional_termial(Float::with_val(FLOAT_PRECISION, 170.624376)).to_f64(),
808 14641.65103069469
809 );
810 }
811
812 fn format_approximate((x, e): (Float, Integer)) -> String {
816 let (x, e) = (x, e);
817 let x = x.to_f64();
818 format!("{x} × 10^{e}")
819 }
820
821 #[test]
822 fn test_approximate_factorial() {
823 assert_eq!(
825 format_approximate(approximate_factorial(100_001.into(), FLOAT_PRECISION)),
826 "2.8242576502544274 × 10^456578"
827 );
828 assert_eq!(
829 format_approximate(approximate_factorial(
830 2_546_372_899u128.into(),
831 FLOAT_PRECISION
832 )),
833 "7.754784101805052 × 10^22845109185"
834 );
835 assert_eq!(
836 format_approximate(approximate_factorial(
837 500_000_000_000u128.into(),
838 FLOAT_PRECISION
839 )),
840 "4.286111886996677 × 10^5632337761222"
841 );
842 assert_eq!(
843 format_approximate(approximate_factorial(
844 712_460_928_486u128.into(),
845 FLOAT_PRECISION
846 )),
847 "2.988979640465335 × 10^8135211294800"
848 );
849 assert_eq!(
850 format_approximate(approximate_factorial(
851 8_392_739_232_838_237_120u128.into(),
852 FLOAT_PRECISION
853 )),
854 "5.321682559738788 × 10^155178468932549925384"
855 );
856 assert_eq!(
857 format_approximate(approximate_factorial(
858 78_473_843_792_461_001_798_392_739_232_838_237_120u128.into(),
859 FLOAT_PRECISION
860 )),
861 "1.726535267725453 × 10^2939663967042394848929844071091736224040"
862 );
863 assert_eq!(
864 format_approximate(approximate_factorial(u128::MAX.into(), FLOAT_PRECISION)),
865 "4.780505917797121 × 10^12963922773915897352139996524992575205341"
866 );
867 assert_eq!(
868 format_approximate(approximate_factorial(
869 Integer::from_str(
870 "1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
871 )
872 .unwrap()
873 , FLOAT_PRECISION)),
874 "6.185167193060592 × 10^197565705518096748172348871081083394917705602994196333433885546216834135350791129225270775050661568251681293893255233696266358320712841036093430778935337187734147872913431329670406629130341173311668935"
875 );
876 assert_eq!(
877 format_approximate(approximate_factorial(
878 Integer::from_str(&format!("1{}", "0".repeat(300))).unwrap(),
879 FLOAT_PRECISION
880 )),
881 "4.6075702908405205 × 10^299565705518096748172348871081083394917705602994196333433885546216834135350791129225270775050661568251681293893255233696266358320712841036093430778935337187734147872913431329670406629130341173311668836392261509485715565133323135341391486443851787651234656456564268274616437771860439695135334763390446212"
883 );
884 }
885 #[test]
886 #[ignore = "future_improvement"]
887 fn test_approximate_factorial_perfect() {
888 assert_eq!(
890 format_approximate(approximate_factorial(100_001.into(), FLOAT_PRECISION)),
891 "2.8242576502544275 × 10^456578"
892 );
893 assert_eq!(
894 format_approximate(approximate_factorial(
895 2_546_372_899u128.into(),
896 FLOAT_PRECISION
897 )),
898 "7.7547841018050521 × 10^22845109185"
899 );
900 assert_eq!(
901 format_approximate(approximate_factorial(
902 500_000_000_000u128.into(),
903 FLOAT_PRECISION
904 )),
905 "4.2861118869966772 × 10^5632337761222"
906 );
907 assert_eq!(
908 format_approximate(approximate_factorial(
909 712_460_928_486u128.into(),
910 FLOAT_PRECISION
911 )),
912 "2.988979640465335 × 10^8135211294800"
913 );
914 assert_eq!(
915 format_approximate(approximate_factorial(
916 8_392_739_232_838_237_120u128.into(),
917 FLOAT_PRECISION
918 )),
919 "5.321682559738788 × 10^155178468932549925384"
920 );
921 assert_eq!(
922 format_approximate(approximate_factorial(
923 78_473_843_792_461_001_798_392_739_232_838_237_120u128.into(),
924 FLOAT_PRECISION
925 )),
926 "1.726535267725453 × 10^2939663967042394848929844071091736224040"
927 );
928 assert_eq!(
929 format_approximate(approximate_factorial(u128::MAX.into(), FLOAT_PRECISION)),
930 "4.780505917797121 × 10^12963922773915897352139996524992575205341"
931 );
932 assert_eq!(
933 format_approximate(approximate_factorial(
934 Integer::from_str(
935 "1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
936 )
937 .unwrap()
938 , FLOAT_PRECISION)),
939 "6.185167193060592 × 10^197565705518096748172348871081083394917705602994196333433885546216834135350791129225270775050661568251681293893255233696266358320712841036093430778935337187734147872913431329670406629130341173311668935"
940 );
941 assert_eq!(
942 format_approximate(approximate_factorial(
943 Integer::from_str(&format!("1{}", "0".repeat(300))).unwrap(),
944 FLOAT_PRECISION
945 )),
946 "4.6075738185461799 × 10^299565705518096748172348871081083394917705602994196333433885546216834135350791129225270775050661568251681293893255233696266358320712841036093430778935337187734147872913431329670406629130341173311668836392261509485715565133323135341391486443851787651234656456564268274616437771860439695135334763390446212"
947 );
948 }
949 #[test]
950 fn test_approximate_multifactorial() {
951 assert_eq!(
953 format_approximate(approximate_multifactorial(
954 100_001.into(),
955 2,
956 FLOAT_PRECISION
957 )),
958 "2.669462450117582 × 10^228290"
959 );
960 assert_eq!(
961 format_approximate(approximate_multifactorial(
962 2_546_372_899u128.into(),
963 2,
964 FLOAT_PRECISION
965 )),
966 "1.766995271233595 × 10^11422554595"
967 );
968 assert_eq!(
969 format_approximate(approximate_multifactorial(
970 500_000_000_000u128.into(),
971 2,
972 FLOAT_PRECISION
973 )),
974 "1.948965818007459 × 10^2816168880614"
975 );
976 assert_eq!(
977 format_approximate(approximate_multifactorial(
978 712_460_928_486u128.into(),
979 2,
980 FLOAT_PRECISION
981 )),
982 "1.778204523968013 × 10^4067605647403"
983 );
984 assert_eq!(
985 format_approximate(approximate_multifactorial(
986 8_392_739_232_838_237_120u128.into(),
987 2,
988 FLOAT_PRECISION
989 )),
990 "1.3900498788571092 × 10^77589234466274962697"
991 );
992 assert_eq!(
993 format_approximate(approximate_multifactorial(
994 78_473_843_792_461_001_798_392_739_232_838_237_120u128.into(),
995 2,
996 FLOAT_PRECISION
997 )),
998 "4.3782335812047535 × 10^1469831983521197424464922035545868112029" );
1000 assert_eq!(
1001 format_approximate(approximate_multifactorial(
1002 u128::MAX.into(),
1003 2,
1004 FLOAT_PRECISION
1005 )),
1006 "2.652569807741017 × 10^6481961386957948676069998262496287602680"
1007 );
1008 assert_eq!(
1009 format_approximate(approximate_multifactorial(
1010 Integer::from_str(
1011 "1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
1012 )
1013 .unwrap(),2
1014 , FLOAT_PRECISION)),
1015 "2.784233733852614 × 10^98782852759048374086174435540541697458852801497098166716942773108417067675395564612635387525330784125840646946627616848133179160356420518046715389467668593867073936456715664835203314565170586655834517"
1016 );
1017 assert_eq!(
1018 format_approximate(approximate_multifactorial(
1019 Integer::from_str(&format!("1{}", "0".repeat(300))).unwrap(),
1020 2,
1021 FLOAT_PRECISION
1022 )),
1023 "2.4030665584107203 × 10^149782852759048374086174435540541697458852801497098166716942773108417067675395564612635387525330784125840646946627616848133179160356420518046715389467668593867073936456715664835203314565170586655834418196130754742857782566661567670695743221925893825617328228282134137308218885930219847567667381695223181"
1025 );
1026 }
1027 #[test]
1028 #[ignore = "future_improvement"]
1029 fn test_approximate_multifactorial_perfect() {
1030 assert_eq!(
1032 format_approximate(approximate_multifactorial(
1033 100_001.into(),
1034 2,
1035 FLOAT_PRECISION
1036 )),
1037 "2.669462450117582 × 10^228290"
1038 );
1039 assert_eq!(
1040 format_approximate(approximate_multifactorial(
1041 2_546_372_899u128.into(),
1042 2,
1043 FLOAT_PRECISION
1044 )),
1045 "1.766995271233595 × 10^11422554595"
1046 );
1047 assert_eq!(
1048 format_approximate(approximate_multifactorial(
1049 500_000_000_000u128.into(),
1050 2,
1051 FLOAT_PRECISION
1052 )),
1053 "1.948965818007459 × 10^2816168880614"
1054 );
1055 assert_eq!(
1056 format_approximate(approximate_multifactorial(
1057 712_460_928_486u128.into(),
1058 2,
1059 FLOAT_PRECISION
1060 )),
1061 "1.778204523968013 × 10^4067605647403"
1062 );
1063 assert_eq!(
1064 format_approximate(approximate_multifactorial(
1065 8_392_739_232_838_237_120u128.into(),
1066 2,
1067 FLOAT_PRECISION
1068 )),
1069 "1.3900498788571092 × 10^77589234466274962697"
1070 );
1071 assert_eq!(
1072 format_approximate(approximate_multifactorial(
1073 78_473_843_792_461_001_798_392_739_232_838_237_120u128.into(),
1074 2,
1075 FLOAT_PRECISION
1076 )),
1077 "4.3782335812047533 × 10^1469831983521197424464922035545868112029"
1078 );
1079 assert_eq!(
1080 format_approximate(approximate_multifactorial(
1081 u128::MAX.into(),
1082 2,
1083 FLOAT_PRECISION
1084 )),
1085 "2.652569807741017 × 10^6481961386957948676069998262496287602680"
1086 );
1087 assert_eq!(
1088 format_approximate(approximate_multifactorial(
1089 Integer::from_str(
1090 "1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
1091 )
1092 .unwrap(),2
1093 , FLOAT_PRECISION)),
1094 "2.784233733852614 × 10^98782852759048374086174435540541697458852801497098166716942773108417067675395564612635387525330784125840646946627616848133179160356420518046715389467668593867073936456715664835203314565170586655834517"
1095 );
1096 assert_eq!(
1097 format_approximate(approximate_multifactorial(
1098 Integer::from_str(&format!("1{}", "0".repeat(300))).unwrap(),
1099 2,
1100 FLOAT_PRECISION
1101 )),
1102 "2.4030683314272798 × 10^149782852759048374086174435540541697458852801497098166716942773108417067675395564612635387525330784125840646946627616848133179160356420518046715389467668593867073936456715664835203314565170586655834418196130754742857782566661567670695743221925893825617328228282134137308218885930219847567667381695223181"
1103 );
1104 }
1105 #[test]
1106 fn test_approximate_subfactorial() {
1107 assert_eq!(
1109 format_approximate(approximate_subfactorial(100_001.into(), FLOAT_PRECISION)),
1110 "1.0389863260997696 × 10^456578"
1111 );
1112 assert_eq!(
1113 format_approximate(approximate_subfactorial(
1114 2_546_372_899u128.into(),
1115 FLOAT_PRECISION
1116 )),
1117 "2.852825641777228 × 10^22845109185"
1118 );
1119 assert_eq!(
1120 format_approximate(approximate_subfactorial(
1121 500_000_000_000u128.into(),
1122 FLOAT_PRECISION
1123 )),
1124 "1.5767724457866137 × 10^5632337761222"
1125 );
1126 assert_eq!(
1127 format_approximate(approximate_subfactorial(
1128 712_460_928_486u128.into(),
1129 FLOAT_PRECISION
1130 )),
1131 "1.099584159807206 × 10^8135211294800"
1132 );
1133 assert_eq!(
1134 format_approximate(approximate_subfactorial(
1135 8_392_739_232_838_237_120u128.into(),
1136 FLOAT_PRECISION
1137 )),
1138 "1.957737606168516 × 10^155178468932549925384"
1139 );
1140 assert_eq!(
1141 format_approximate(approximate_subfactorial(
1142 78_473_843_792_461_001_798_392_739_232_838_237_120u128.into(),
1143 FLOAT_PRECISION
1144 )),
1145 "6.3515682945362615 × 10^2939663967042394848929844071091736224039"
1146 );
1147 assert_eq!(
1148 format_approximate(approximate_subfactorial(u128::MAX.into(), FLOAT_PRECISION)),
1149 "1.7586498455559778 × 10^12963922773915897352139996524992575205341"
1150 );
1151 assert_eq!(
1152 format_approximate(approximate_subfactorial(
1153 Integer::from_str(
1154 "1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
1155 )
1156 .unwrap()
1157 , FLOAT_PRECISION)),
1158 "2.275395850535069 × 10^197565705518096748172348871081083394917705602994196333433885546216834135350791129225270775050661568251681293893255233696266358320712841036093430778935337187734147872913431329670406629130341173311668935"
1159 );
1160 assert_eq!(
1161 format_approximate(approximate_subfactorial(
1162 Integer::from_str(&format!("1{}", "0".repeat(300))).unwrap(),
1163 FLOAT_PRECISION
1164 )),
1165 "1.6950303837525507 × 10^299565705518096748172348871081083394917705602994196333433885546216834135350791129225270775050661568251681293893255233696266358320712841036093430778935337187734147872913431329670406629130341173311668836392261509485715565133323135341391486443851787651234656456564268274616437771860439695135334763390446212"
1167 );
1168 }
1169 #[test]
1170 #[ignore = "future_improvement"]
1171 fn test_approximate_subfactorial_perfect() {
1172 assert_eq!(
1174 format_approximate(approximate_subfactorial(100_001.into(), FLOAT_PRECISION)),
1175 "1.0389863260997696 × 10^456578"
1176 );
1177 assert_eq!(
1178 format_approximate(approximate_subfactorial(
1179 2_546_372_899u128.into(),
1180 FLOAT_PRECISION
1181 )),
1182 "2.852825641777228 × 10^22845109185"
1183 );
1184 assert_eq!(
1185 format_approximate(approximate_subfactorial(
1186 500_000_000_000u128.into(),
1187 FLOAT_PRECISION
1188 )),
1189 "1.5767724457866138 × 10^5632337761222"
1190 );
1191 assert_eq!(
1192 format_approximate(approximate_subfactorial(
1193 712_460_928_486u128.into(),
1194 FLOAT_PRECISION
1195 )),
1196 "1.099584159807206 × 10^8135211294800"
1197 );
1198 assert_eq!(
1199 format_approximate(approximate_subfactorial(
1200 8_392_739_232_838_237_120u128.into(),
1201 FLOAT_PRECISION
1202 )),
1203 "1.957737606168516 × 10^155178468932549925384"
1204 );
1205 assert_eq!(
1206 format_approximate(approximate_subfactorial(
1207 78_473_843_792_461_001_798_392_739_232_838_237_120u128.into(),
1208 FLOAT_PRECISION
1209 )),
1210 "6.3515682945362619 × 10^2939663967042394848929844071091736224039"
1211 );
1212 assert_eq!(
1213 format_approximate(approximate_subfactorial(u128::MAX.into(), FLOAT_PRECISION)),
1214 "1.7586498455559779 × 10^12963922773915897352139996524992575205341"
1215 );
1216 assert_eq!(
1217 format_approximate(approximate_subfactorial(
1218 Integer::from_str(
1219 "1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
1220 )
1221 .unwrap()
1222 , FLOAT_PRECISION)),
1223 "2.275395850535069 × 10^197565705518096748172348871081083394917705602994196333433885546216834135350791129225270775050661568251681293893255233696266358320712841036093430778935337187734147872913431329670406629130341173311668935"
1224 );
1225 assert_eq!(
1226 format_approximate(approximate_subfactorial(
1227 Integer::from_str(&format!("1{}", "0".repeat(300))).unwrap(),
1228 FLOAT_PRECISION
1229 )),
1230 "1.6950316815229372 × 10^299565705518096748172348871081083394917705602994196333433885546216834135350791129225270775050661568251681293893255233696266358320712841036093430778935337187734147872913431329670406629130341173311668836392261509485715565133323135341391486443851787651234656456564268274616437771860439695135334763390446212"
1231 );
1232 }
1233 #[test]
1234 fn test_approximate_termial() {
1235 assert_eq!(
1237 format_approximate(approximate_termial(100_001.into(), 1, FLOAT_PRECISION)),
1238 "5.000150001 × 10^9"
1239 );
1240 assert_eq!(
1241 format_approximate(approximate_termial(
1242 2_546_372_899u128.into(),
1243 1,
1244 FLOAT_PRECISION
1245 )),
1246 "3.2420074716540186 × 10^18"
1247 );
1248 assert_eq!(
1249 format_approximate(approximate_termial(
1250 500_000_000_000u128.into(),
1251 1,
1252 FLOAT_PRECISION
1253 )),
1254 "1.2500000000025 × 10^23"
1255 );
1256 assert_eq!(
1257 format_approximate(approximate_termial(
1258 712_460_928_486u128.into(),
1259 1,
1260 FLOAT_PRECISION
1261 )),
1262 "2.538002873099228 × 10^23"
1263 );
1264 assert_eq!(
1265 format_approximate(approximate_termial(
1266 8_392_739_232_838_237_120u128.into(),
1267 1,
1268 FLOAT_PRECISION
1269 )),
1270 "3.521903591521108 × 10^37"
1271 );
1272 assert_eq!(
1273 format_approximate(approximate_termial(
1274 78_473_843_792_461_001_798_392_739_232_838_237_120u128.into(),
1275 1,
1276 FLOAT_PRECISION
1277 )),
1278 "3.079072079781785 × 10^75"
1279 );
1280 assert_eq!(
1281 format_approximate(approximate_termial(u128::MAX.into(), 1, FLOAT_PRECISION)),
1282 "5.789604461865809 × 10^76"
1283 );
1284 assert_eq!(
1285 format_approximate(approximate_termial(
1286 Integer::from_str(
1287 "1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
1288 )
1289 .unwrap(),1
1290 , FLOAT_PRECISION)),
1291 "5 × 10^395"
1292 );
1293 assert_eq!(
1294 format_approximate(approximate_termial(
1295 Integer::from_str(&format!("1{}", "0".repeat(300))).unwrap(),
1296 1,
1297 FLOAT_PRECISION
1298 )),
1299 "5 × 10^599"
1300 );
1301 let mut max = Float::with_val(FLOAT_PRECISION, rug::float::Special::Infinity);
1302 max.next_down();
1303 assert_eq!(
1304 format_approximate(approximate_termial(
1305 max.to_integer().unwrap(),
1306 1,
1307 FLOAT_PRECISION
1308 )),
1309 "2.202016314604954 × 10^646456992"
1310 );
1311 assert_eq!(
1312 format_approximate(approximate_termial(100_001.into(), 2, FLOAT_PRECISION)),
1313 "2.50010000075 × 10^9"
1314 );
1315 assert_eq!(
1316 format_approximate(approximate_termial(
1317 2_546_372_899u128.into(),
1318 2,
1319 FLOAT_PRECISION
1320 )),
1321 "1.6210037364636025 × 10^18"
1322 );
1323 assert_eq!(
1324 format_approximate(approximate_termial(
1325 500_000_000_000u128.into(),
1326 2,
1327 FLOAT_PRECISION
1328 )),
1329 "6.250000000025 × 10^22"
1330 );
1331 assert_eq!(
1332 format_approximate(approximate_termial(
1333 712_460_928_486u128.into(),
1334 2,
1335 FLOAT_PRECISION
1336 )),
1337 "1.2690014365513953 × 10^23"
1338 );
1339 assert_eq!(
1340 format_approximate(approximate_termial(
1341 8_392_739_232_838_237_120u128.into(),
1342 2,
1343 FLOAT_PRECISION
1344 )),
1345 "1.760951795760554 × 10^37"
1346 );
1347 assert_eq!(
1348 format_approximate(approximate_termial(
1349 78_473_843_792_461_001_798_392_739_232_838_237_120u128.into(),
1350 2,
1351 FLOAT_PRECISION
1352 )),
1353 "1.5395360398908926 × 10^75"
1354 );
1355 assert_eq!(
1356 format_approximate(approximate_termial(u128::MAX.into(), 2, FLOAT_PRECISION)),
1357 "2.8948022309329047 × 10^76"
1358 );
1359 assert_eq!(
1360 format_approximate(approximate_termial(
1361 Integer::from_str(
1362 "1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
1363 )
1364 .unwrap()
1365 ,2
1366 , FLOAT_PRECISION)),
1367 "2.5 × 10^395"
1368 );
1369 assert_eq!(
1370 format_approximate(approximate_termial(
1371 Integer::from_str(&format!("1{}", "0".repeat(300))).unwrap(),
1372 2,
1373 FLOAT_PRECISION
1374 )),
1375 "2.5 × 10^599"
1376 );
1377 assert_eq!(
1378 format_approximate(approximate_termial(u128::MAX.into(), 2, FLOAT_PRECISION)),
1379 "2.8948022309329047 × 10^76"
1380 );
1381 assert_eq!(
1382 format_approximate(approximate_termial(u128::MAX.into(), 5, FLOAT_PRECISION)),
1383 "1.1579208923731619 × 10^76"
1384 );
1385 assert_eq!(
1386 format_approximate(approximate_termial(u128::MAX.into(), 20, FLOAT_PRECISION)),
1387 "2.8948022309329047 × 10^75"
1388 );
1389 assert_eq!(
1390 format_approximate(approximate_termial(u128::MAX.into(), 200, FLOAT_PRECISION)),
1391 "2.8948022309329047 × 10^74"
1392 );
1393 assert_eq!(
1394 format_approximate(approximate_termial(
1395 u128::MAX.into(),
1396 20000,
1397 FLOAT_PRECISION
1398 )),
1399 "2.8948022309329047 × 10^72"
1400 );
1401 assert_eq!(
1402 format_approximate(approximate_termial(
1403 u128::MAX.into(),
1404 2000000,
1405 FLOAT_PRECISION
1406 )),
1407 "2.8948022309329047 × 10^70"
1408 );
1409 }
1410 #[test]
1411 #[ignore = "future_improvement"]
1412 fn test_approximate_termial_perfect() {
1413 assert_eq!(
1415 format_approximate(approximate_termial(100_001.into(), 1, FLOAT_PRECISION)),
1416 "5.000150001 × 10^9"
1417 );
1418 assert_eq!(
1419 format_approximate(approximate_termial(
1420 2_546_372_899u128.into(),
1421 1,
1422 FLOAT_PRECISION
1423 )),
1424 "3.2420074716540186 × 10^18"
1425 );
1426 assert_eq!(
1427 format_approximate(approximate_termial(
1428 500_000_000_000u128.into(),
1429 1,
1430 FLOAT_PRECISION
1431 )),
1432 "1.2500000000025 × 10^23"
1433 );
1434 assert_eq!(
1435 format_approximate(approximate_termial(
1436 712_460_928_486u128.into(),
1437 1,
1438 FLOAT_PRECISION
1439 )),
1440 "2.538002873099228 × 10^23"
1441 );
1442 assert_eq!(
1443 format_approximate(approximate_termial(
1444 8_392_739_232_838_237_120u128.into(),
1445 1,
1446 FLOAT_PRECISION
1447 )),
1448 "3.521903591521108 × 10^37"
1449 );
1450 assert_eq!(
1451 format_approximate(approximate_termial(
1452 78_473_843_792_461_001_798_392_739_232_838_237_120u128.into(),
1453 1,
1454 FLOAT_PRECISION
1455 )),
1456 "3.079072079781785 × 10^75"
1457 );
1458 assert_eq!(
1459 format_approximate(approximate_termial(u128::MAX.into(), 1, FLOAT_PRECISION)),
1460 "5.78960446186581 × 10^76"
1461 );
1462 assert_eq!(
1463 format_approximate(approximate_termial(
1464 Integer::from_str(
1465 "1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
1466 )
1467 .unwrap(),1
1468 , FLOAT_PRECISION)),
1469 "5 × 10^395"
1470 );
1471 assert_eq!(
1472 format_approximate(approximate_termial(
1473 Integer::from_str(&format!("1{}", "0".repeat(300))).unwrap(),
1474 1,
1475 FLOAT_PRECISION
1476 )),
1477 "5 × 10^599"
1478 );
1479 let mut max = Float::with_val(FLOAT_PRECISION, rug::float::Special::Infinity);
1480 max.next_down();
1481 assert_eq!(
1482 format_approximate(approximate_termial(
1483 max.to_integer().unwrap(),
1484 1,
1485 FLOAT_PRECISION
1486 )),
1487 "2.202016314604954 × 10^646456992"
1488 );
1489 }
1490
1491 #[test]
1492 fn test_approximate_digits() {
1493 assert_eq!(
1494 approximate_multifactorial_digits(100_001.into(), 1, FLOAT_PRECISION),
1495 456_579u128
1496 );
1497 assert_eq!(
1498 approximate_multifactorial_digits(7_834_436_739u128.into(), 1, FLOAT_PRECISION),
1499 74_111_525_394u128
1500 );
1501 assert_eq!(
1502 approximate_multifactorial_digits(738_247_937_346_920u128.into(), 1, FLOAT_PRECISION),
1503 10_655_802_631_914_633u128
1504 );
1505 assert_eq!(
1506 approximate_multifactorial_digits(
1507 827_829_849_020_729_846u128.into(),
1508 1,
1509 FLOAT_PRECISION
1510 ),
1511 14_473_484_525_026_753_452u128
1512 );
1513 assert_eq!(
1514 approximate_multifactorial_digits(
1515 1_000_000_000_000_000_000u128.into(),
1516 1,
1517 FLOAT_PRECISION
1518 ),
1519 17_565_705_518_096_748_182u128
1520 );
1521 assert_eq!(
1522 approximate_multifactorial_digits(
1523 1_000_000_000_000_000_000_000_000_000_000_000_000u128.into(),
1524 1,
1525 FLOAT_PRECISION
1526 ),
1527 35_565_705_518_096_748_172_348_871_081_083_394_936u128 );
1529 assert_eq!(
1530 approximate_multifactorial_digits(u128::MAX.into(), 1, FLOAT_PRECISION),
1531 Integer::from_str("12963922773915897352139996524992575205342").unwrap()
1532 );
1533 assert_eq!(
1534 approximate_multifactorial_digits(
1535 Integer::from_str(
1536 "1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
1537 )
1538 .unwrap(),
1539 1
1540 , FLOAT_PRECISION),
1541 Integer::from_str("197565705518096748172348871081083394917705602994196333433885546216834135350791129225270775050661568251681293893255233696266358320712841036093430778935337187734147872913431329670406629130341173311668936").unwrap()
1542 );
1543 assert_eq!(
1544 approximate_multifactorial_digits(100_001.into(), 2, FLOAT_PRECISION),
1545 228_291u128
1546 );
1547 assert_eq!(
1548 approximate_multifactorial_digits(7_834_436_739u128.into(), 2, FLOAT_PRECISION),
1549 37_055_762_699u128
1550 );
1551 assert_eq!(
1552 approximate_multifactorial_digits(738_247_937_346_920u128.into(), 2, FLOAT_PRECISION),
1553 5_327_901_315_957_320u128 );
1555 assert_eq!(
1556 approximate_multifactorial_digits(
1557 827_829_849_020_729_846u128.into(),
1558 2,
1559 FLOAT_PRECISION
1560 ),
1561 7_236_742_262_513_376_731u128
1562 );
1563 }
1565
1566 #[test]
1567 #[ignore = "future_improvement"]
1568 fn test_approximate_digits_perfect() {
1569 assert_eq!(
1571 approximate_multifactorial_digits(100_001.into(), 1, FLOAT_PRECISION),
1572 456_579u128
1573 );
1574 assert_eq!(
1575 approximate_multifactorial_digits(7_834_436_739u128.into(), 1, FLOAT_PRECISION),
1576 74_111_525_394u128
1577 );
1578 assert_eq!(
1579 approximate_multifactorial_digits(738_247_937_346_920u128.into(), 1, FLOAT_PRECISION),
1580 10_655_802_631_914_633u128
1581 );
1582 assert_eq!(
1583 approximate_multifactorial_digits(
1584 827_829_849_020_729_846u128.into(),
1585 1,
1586 FLOAT_PRECISION
1587 ),
1588 14_473_484_525_026_753_452u128
1589 );
1590 assert_eq!(
1591 approximate_multifactorial_digits(
1592 1_000_000_000_000_000_000u128.into(),
1593 1,
1594 FLOAT_PRECISION
1595 ),
1596 17_565_705_518_096_748_182u128
1597 );
1598 assert_eq!(
1599 approximate_multifactorial_digits(
1600 1_000_000_000_000_000_000_000_000_000_000_000_000u128.into(),
1601 1,
1602 FLOAT_PRECISION
1603 ),
1604 35_565_705_518_096_748_172_348_871_081_083_394_937u128
1605 );
1606 assert_eq!(
1607 approximate_multifactorial_digits(u128::MAX.into(), 1, FLOAT_PRECISION),
1608 Integer::from_str("12963922773915897352139996524992575205342").unwrap()
1609 );
1610 assert_eq!(
1611 approximate_multifactorial_digits(
1612 Integer::from_str(
1613 "1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
1614 )
1615 .unwrap(),
1616 1
1617 , FLOAT_PRECISION),
1618 Integer::from_str("197565705518096748172348871081083394917705602994196333433885546216834135350791129225270775050661568251681293893255233696266358320712841036093430778935337187734147872913431329670406629130341173311668936").unwrap()
1619 );
1620 assert_eq!(
1621 approximate_multifactorial_digits(100_001.into(), 2, FLOAT_PRECISION),
1622 228_291u128
1623 );
1624 assert_eq!(
1625 approximate_multifactorial_digits(7_834_436_739u128.into(), 2, FLOAT_PRECISION),
1626 37_055_762_699u128
1627 );
1628 assert_eq!(
1629 approximate_multifactorial_digits(738_247_937_346_920u128.into(), 2, FLOAT_PRECISION),
1630 5_327_901_315_957_321u128
1631 );
1632 assert_eq!(
1633 approximate_multifactorial_digits(
1634 827_829_849_020_729_846u128.into(),
1635 2,
1636 FLOAT_PRECISION
1637 ),
1638 7_236_742_262_513_376_731u128
1639 );
1640 }
1641
1642 #[test]
1643 fn test_approximate_termial_digits() {
1644 assert_eq!(
1645 approximate_termial_digits(100_001.into(), 1, FLOAT_PRECISION),
1646 9
1647 );
1648 assert_eq!(
1649 approximate_termial_digits(7_834_436_739u128.into(), 1, FLOAT_PRECISION),
1650 19
1651 );
1652 assert_eq!(
1653 approximate_termial_digits(738_247_937_346_920u128.into(), 1, FLOAT_PRECISION),
1654 29
1655 );
1656 assert_eq!(
1657 approximate_termial_digits(827_829_849_020_729_846u128.into(), 1, FLOAT_PRECISION),
1658 35
1659 );
1660 assert_eq!(
1661 approximate_termial_digits(1_000_000_000_000_000_000u128.into(), 1, FLOAT_PRECISION),
1662 35
1663 );
1664 assert_eq!(
1665 approximate_termial_digits(
1666 1_000_000_000_000_000_000_000_000_000_000_000_000u128.into(),
1667 1,
1668 FLOAT_PRECISION
1669 ),
1670 71
1671 );
1672 assert_eq!(
1673 approximate_termial_digits(u128::MAX.into(), 1, FLOAT_PRECISION),
1674 76
1675 );
1676 assert_eq!(
1677 approximate_termial_digits(
1678 Integer::from_str(
1679 "1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
1680 )
1681 .unwrap(),1,
1682 FLOAT_PRECISION),
1683 395
1684 );
1685 assert_eq!(
1686 approximate_termial_digits(
1687 Integer::from_str(&format!("1{}", "0".repeat(1000000))).unwrap(),
1688 1,
1689 FLOAT_PRECISION
1690 ),
1691 1999999
1692 );
1693 assert_eq!(
1694 approximate_termial_digits(
1695 1_000_000_000_000_000_000_000_000_000_000_000_000u128.into(),
1696 2,
1697 FLOAT_PRECISION
1698 ),
1699 71
1700 );
1701 assert_eq!(
1702 approximate_termial_digits(
1703 1_000_000_000_000_000_000_000_000_000_000_000_000u128.into(),
1704 10,
1705 FLOAT_PRECISION
1706 ),
1707 70
1708 );
1709 assert_eq!(
1710 approximate_termial_digits(
1711 1_000_000_000_000_000_000_000_000_000_000_000_000u128.into(),
1712 10000,
1713 FLOAT_PRECISION
1714 ),
1715 67
1716 );
1717 }
1718
1719 #[test]
1720 fn test_negative_multifacorial_factor() {
1721 assert_eq!(negative_multifacorial_factor(6.into(), 3), None);
1723 assert_eq!(
1725 negative_multifacorial_factor(Integer::from(-1), 3),
1726 Some(Integer::ONE.clone())
1727 );
1728 assert_eq!(negative_multifacorial_factor(5.into(), -5), None);
1730 assert_eq!(
1732 negative_multifacorial_factor(1.into(), -3),
1733 Some(Integer::NEG_ONE.clone())
1734 );
1735 }
1736
1737 #[test]
1738 fn test_adjust_approximate() {
1739 let input = (Float::with_val(FLOAT_PRECISION, 100.0), Integer::from(2));
1740 let (x, e) = adjust_approximate(input);
1741 assert_eq!(x, 1.0);
1742 assert_eq!(e, 4);
1743 }
1744
1745 #[test]
1746 #[should_panic]
1747 fn test_approximate_factorial_with_n_is_non_positive() {
1748 let _ = approximate_factorial(0.into(), FLOAT_PRECISION);
1749 }
1750
1751 #[test]
1752 #[should_panic]
1753 fn test_approximate_multifactorial_with_n_is_non_positive() {
1754 let _ = approximate_multifactorial(0.into(), 1, FLOAT_PRECISION);
1755 }
1756
1757 #[test]
1758 #[should_panic]
1759 fn test_approximate_multifactorial_with_k_is_non_positive() {
1760 let _ = approximate_multifactorial(1.into(), 0, FLOAT_PRECISION);
1761 }
1762
1763 #[test]
1764 #[should_panic]
1765 fn test_approximate_multifactorial_digits_with_n_is_non_positive() {
1766 let _ = approximate_multifactorial_digits(0.into(), 1, FLOAT_PRECISION);
1767 }
1768
1769 #[test]
1770 #[should_panic]
1771 fn test_approximate_multifactorial_digits_with_k_is_non_positive() {
1772 let _ = approximate_multifactorial_digits(1.into(), 0, FLOAT_PRECISION);
1773 }
1774}