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