1use crate::format::{
4 format_float, get_factorial_level_string, replace, truncate, write_out_number,
5};
6use crate::impl_all_bitwise;
7use crate::impl_bitwise;
8use factorion_math::length;
9#[cfg(any(feature = "serde", test))]
10use serde::{Deserialize, Serialize};
11use std::ops::BitAnd;
12use std::ops::BitOr;
13use std::ops::BitXor;
14use std::ops::Not;
15
16use crate::rug::float::OrdFloat;
17use crate::rug::ops::{NegAssign, NotAssign};
18use crate::rug::{Float, Integer};
19use crate::{Consts, locale};
20use std::fmt;
21use std::fmt::Write;
22
23pub mod recommended {
24 pub const NUMBER_DECIMALS_SCIENTIFIC: usize = 30;
25}
26
27impl fmt::Debug for CalculationResult {
28 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
29 fn truncate<T: fmt::Debug>(val: &T) -> String {
30 let s = format!("{val:?}");
31 if s.len() > 25 {
32 format!("{}...", &s[..20])
33 } else {
34 s
35 }
36 }
37
38 match self {
39 CalculationResult::Exact(n) => write!(f, "Exact({})", truncate(n)),
40 CalculationResult::Approximate(of, int) => {
41 write!(
42 f,
43 "Approximate({}, {})",
44 truncate(&of.as_float()),
45 truncate(int)
46 )
47 }
48 CalculationResult::ApproximateDigits(i, n) => {
49 write!(f, "ApproximateDigits({}, {})", i, truncate(n))
50 }
51 CalculationResult::ApproximateDigitsTower(i, b, u, n) => {
52 write!(
53 f,
54 "ApproximateDigitsTower({}, {}, {}, {})",
55 i,
56 b,
57 u,
58 truncate(n)
59 )
60 }
61 CalculationResult::Float(of) => write!(f, "Float({})", truncate(&of.as_float())),
62 CalculationResult::ComplexInfinity => write!(f, "ComplexInfinity"),
63 }
64 }
65}
66
67#[derive(Clone, PartialEq, Ord, Eq, Hash, PartialOrd)]
69#[cfg_attr(any(feature = "serde", test), derive(Serialize, Deserialize))]
70pub enum CalculationResult {
71 Exact(Integer),
72 Approximate(OrdFloat, Integer),
74 ApproximateDigits(bool, Integer),
76 ApproximateDigitsTower(bool, bool, Integer, Integer),
78 Float(OrdFloat),
79 ComplexInfinity,
80}
81
82pub type Number = CalculationResult;
84
85impl Number {
86 pub fn negate(&mut self) {
87 match self {
88 Self::Approximate(x, _) | Self::Float(x) => x.as_float_mut().neg_assign(),
89 Self::Exact(n) => n.neg_assign(),
90 Self::ApproximateDigitsTower(n, _, _, _) | Self::ApproximateDigits(n, _) => {
91 n.not_assign()
92 }
93 Self::ComplexInfinity => {}
94 }
95 }
96 pub fn is_too_long(&self, too_big_number: &Integer) -> bool {
97 let n = match self {
98 CalculationResult::Exact(n)
99 | CalculationResult::ApproximateDigits(_, n)
100 | CalculationResult::Approximate(_, n)
101 | CalculationResult::ApproximateDigitsTower(_, _, _, n) => n,
102 CalculationResult::Float(_) | CalculationResult::ComplexInfinity => return false,
103 };
104 n > too_big_number
105 }
106}
107impl From<Integer> for Number {
108 fn from(value: Integer) -> Self {
109 Number::Exact(value)
110 }
111}
112impl From<i32> for Number {
113 fn from(value: i32) -> Self {
114 Number::Exact(value.into())
115 }
116}
117impl From<Float> for Number {
118 fn from(value: Float) -> Self {
119 Number::Float(value.into())
120 }
121}
122#[non_exhaustive]
123#[derive(Debug, Clone, Default)]
124pub struct FormatOptions {
125 pub force_shorten: bool,
126 pub agressive_shorten: bool,
127 pub write_out: bool,
128}
129impl_all_bitwise!(FormatOptions {
130 force_shorten,
131 agressive_shorten,
132 write_out,
133});
134#[allow(dead_code)]
135impl FormatOptions {
136 pub const NONE: Self = Self {
137 force_shorten: false,
138 agressive_shorten: false,
139 write_out: false,
140 };
141 pub const FORCE_SHORTEN: Self = Self {
142 force_shorten: true,
143 ..Self::NONE
144 };
145 pub const AGRESSIVE_SHORTEN: Self = Self {
146 agressive_shorten: true,
147 ..Self::NONE
148 };
149 pub const WRITE_OUT: Self = Self {
150 write_out: true,
151 ..Self::NONE
152 };
153}
154impl CalculationResult {
155 pub fn format(
159 &self,
160 acc: &mut String,
161 rough: &mut bool,
162 opts: FormatOptions,
163 is_value: bool,
164 consts: &Consts,
165 locale: &locale::NumFormat,
166 ) -> std::fmt::Result {
167 let mut start = acc.len();
168 match &self {
169 CalculationResult::Exact(factorial) => {
170 if opts.write_out && length(factorial, consts.float_precision) < 3000000 {
171 write_out_number(acc, factorial, consts)?;
172 } else if opts.force_shorten {
173 let (s, r) = truncate(factorial, consts);
174 *rough = r;
175 acc.write_str(&s)?;
176 } else {
177 write!(acc, "{factorial}")?;
178 }
179 }
180 CalculationResult::Approximate(base, exponent) => {
181 let base = base.as_float();
182 format_float(acc, base, consts)?;
183 acc.write_str(" × 10^")?;
184 if opts.force_shorten {
185 acc.write_str("(")?;
186 acc.write_str(&truncate(exponent, consts).0)?;
187 acc.write_str(")")?;
188 } else {
189 write!(acc, "{exponent}")?;
190 }
191 }
192 CalculationResult::ApproximateDigits(_, digits) => {
193 if opts.write_out && !is_value && length(digits, consts.float_precision) < 3000000 {
194 write_out_number(acc, digits, consts)?;
195 } else {
196 if is_value {
197 acc.write_str("10^(")?;
198 }
199 if opts.force_shorten {
200 acc.write_str(&truncate(digits, consts).0)?;
201 } else {
202 write!(acc, "{digits}")?;
203 }
204 if is_value {
205 acc.write_str(")")?;
206 }
207 }
208 }
209 CalculationResult::ApproximateDigitsTower(_, negative, depth, exponent) => {
210 let depth = if is_value {
211 depth.clone() + 1
212 } else {
213 depth.clone()
214 };
215 acc.write_str(if *negative { "-" } else { "" })?;
216 if !opts.agressive_shorten && depth <= usize::MAX && (depth <= 1 || exponent != &1)
219 {
220 if depth > 0 {
221 acc.write_str("10^(")?;
222 }
223 if depth > 1 {
224 acc.write_str(&"10\\^".repeat(depth.to_usize().unwrap() - 1))?;
226 acc.write_str("(")?;
227 }
228 if opts.force_shorten {
229 acc.write_str(&truncate(exponent, consts).0)?;
230 } else {
231 write!(acc, "{exponent}")?;
232 }
233 if depth > 1 {
234 acc.write_str("\\)")?;
235 }
236 if depth > 0 {
237 acc.write_str(")")?;
238 }
239 } else {
240 let mut extra = 0;
241 let mut exponent = Float::with_val(consts.float_precision, exponent);
242 while exponent >= 10 {
243 extra += 1;
244 exponent = exponent.log10();
245 }
246 acc.write_str("^(")?;
247 write!(acc, "{}", depth + extra)?;
248 acc.write_str(")10")?;
249 }
250 }
251 CalculationResult::Float(gamma) => {
252 let gamma = gamma.as_float();
253 format_float(acc, gamma, consts)?;
254 }
255 CalculationResult::ComplexInfinity => {
256 if opts.write_out {
257 acc.write_str("complex infinity")?;
258 } else {
259 acc.write_str("∞\u{0303}")?;
260 }
261 }
262 }
263 if locale.decimal != '.' {
264 let decimal = locale.decimal.to_string();
265 while start < acc.len() {
266 start = replace(acc, start, ".", &decimal);
267 }
268 }
269 Ok(())
270 }
271}
272
273#[derive(Debug, Clone, PartialEq, Ord, Eq, Hash, PartialOrd)]
274#[cfg_attr(any(feature = "serde", test), derive(Serialize, Deserialize))]
275pub struct Calculation {
276 pub value: Number,
278 pub steps: Vec<(i32, bool)>,
280 pub result: CalculationResult,
281}
282
283impl Calculation {
284 pub fn is_digit_tower(&self) -> bool {
285 matches!(
286 self,
287 Calculation {
288 result: CalculationResult::ApproximateDigitsTower(_, _, _, _),
289 ..
290 }
291 )
292 }
293 pub fn is_aproximate_digits(&self) -> bool {
294 matches!(
295 self,
296 Calculation {
297 result: CalculationResult::ApproximateDigits(_, _),
298 ..
299 }
300 )
301 }
302 pub fn is_approximate(&self) -> bool {
303 matches!(
304 self,
305 Calculation {
306 result: CalculationResult::Approximate(_, _),
307 ..
308 }
309 )
310 }
311 pub fn is_rounded(&self) -> bool {
312 matches!(
313 self,
314 Calculation {
315 value: Number::Float(_),
316 ..
317 }
318 ) && !matches!(
319 self,
320 Calculation {
321 result: CalculationResult::Float(_),
322 ..
323 }
324 )
325 }
326 pub fn is_too_long(&self, too_big_number: &Integer) -> bool {
327 self.result.is_too_long(too_big_number) || self.value.is_too_long(too_big_number)
328 }
329 pub fn can_write_out(&self, prec: u32) -> bool {
330 let CalculationResult::Exact(n) = &self.result else {
331 return false;
332 };
333
334 length(n, prec) <= 3000000
335 }
336}
337
338impl Calculation {
339 pub fn format(
344 &self,
345 acc: &mut String,
346 options: FormatOptions,
347 too_big_number: &Integer,
348 consts: &Consts,
349 locale: &locale::Format<'_>,
350 ) -> Result<(), std::fmt::Error> {
351 let frame_start = acc.len();
352 acc.write_str(
353 match (
354 &self.value,
355 &self.result,
356 options.agressive_shorten && self.steps.len() > 1,
357 ) {
358 (_, _, true) => &locale.all_that,
360 (_, CalculationResult::ApproximateDigitsTower(_, _, _, _), _) => &locale.order,
362 (_, CalculationResult::ApproximateDigits(_, _), _) => &locale.digits,
364 (Number::Float(_), _, _) | (_, CalculationResult::Approximate(_, _), _) => {
366 &locale.approx
367 }
368 _ => &locale.exact,
370 },
371 )?;
372 acc.write_str(" \n\n")?;
373
374 let mut number = String::new();
375 let mut rough = false;
376 self.value.format(
377 &mut number,
378 &mut rough,
379 FormatOptions {
380 force_shorten: options.force_shorten
381 || self.result.is_too_long(too_big_number)
382 || options.agressive_shorten,
383 ..options
384 },
385 true,
386 consts,
387 &locale.number_format,
388 )?;
389 if rough {
390 replace(acc, frame_start, "{number}", &locale.rough_number);
391 }
392 replace(acc, frame_start, "{number}", &number);
393 replace(acc, frame_start, "{result}", "{number}");
394 let mut number = String::new();
395 let mut rough = false;
396 self.result.format(
397 &mut number,
398 &mut rough,
399 FormatOptions {
400 force_shorten: options.force_shorten
401 || self.result.is_too_long(too_big_number)
402 || options.agressive_shorten,
403 ..options
404 },
405 false,
406 consts,
407 &locale.number_format,
408 )?;
409 if rough {
410 replace(acc, frame_start, "{number}", &locale.rough_number);
411 }
412 replace(acc, frame_start, "{number}", &number);
413
414 let len = self.steps.len();
415 let mut start = frame_start;
416 for (i, (level, neg)) in self.steps.iter().copied().rev().enumerate() {
417 if i != len - 1 {
418 replace(acc, start, "{factorial}", &locale.nest);
419 }
420
421 if neg {
422 replace(acc, start, "{factorial}", "negative {factorial}");
423 }
424
425 let calc_start = replace(
426 acc,
427 start,
428 "{factorial}",
429 &get_factorial_level_string(level.abs(), locale),
430 );
431
432 replace(
433 acc,
434 start,
435 "{factorial}",
436 if level < 0 {
437 &locale.termial
438 } else {
439 &locale.factorial
440 },
441 );
442 if locale.capitalize_calc {
443 let mut ind = acc[calc_start..].char_indices();
444 if let Some((start, _)) = ind.next()
445 && let Some((end, _)) = ind.next()
446 {
447 acc[calc_start..][start..end].make_ascii_uppercase();
448 }
449 }
450
451 if i != len - 1 {
452 start = replace(acc, start, "{next}", "{factorial}");
453 }
454 }
455 let mut ind = acc[frame_start..].char_indices();
456 if let Some((start, _)) = ind.next()
457 && let Some((end, _)) = ind.next()
458 {
459 acc[frame_start..][start..end].make_ascii_uppercase();
460 }
461
462 Ok(())
463 }
464}
465
466#[cfg(test)]
467mod test {
468 use super::*;
469 use crate::recommended::FLOAT_PRECISION;
470 use factorion_math::rug::Complete;
471 use std::{str::FromStr, sync::LazyLock};
472 static TOO_BIG_NUMBER: LazyLock<Integer> =
473 LazyLock::new(|| Integer::from_str(&format!("1{}", "0".repeat(9999))).unwrap());
474
475 #[test]
478 fn test_factorial_format() {
479 let consts = Consts::default();
480 let mut acc = String::new();
481 let factorial = Calculation {
482 value: 5.into(),
483 steps: vec![(1, false)],
484 result: CalculationResult::Exact(Integer::from(120)),
485 };
486 factorial
487 .format(
488 &mut acc,
489 FormatOptions::NONE,
490 &TOO_BIG_NUMBER,
491 &consts,
492 &consts.locales.get("en").unwrap().format,
493 )
494 .unwrap();
495 assert_eq!(acc, "Factorial of 5 is 120 \n\n");
496
497 let mut acc = String::new();
498 let factorial = Calculation {
499 value: 5.into(),
500 steps: vec![(0, false)],
501 result: CalculationResult::Exact(Integer::from(120)),
502 };
503 factorial
504 .format(
505 &mut acc,
506 FormatOptions::NONE,
507 &TOO_BIG_NUMBER,
508 &consts,
509 &consts.locales.get("en").unwrap().format,
510 )
511 .unwrap();
512 assert_eq!(acc, "Subfactorial of 5 is 120 \n\n");
513
514 let mut acc = String::new();
515 let factorial = Calculation {
516 value: 5.into(),
517 steps: vec![(1, false)],
518 result: CalculationResult::Approximate(
519 Float::with_val(FLOAT_PRECISION, Float::parse("1.2").unwrap()).into(),
520 5.into(),
521 ),
522 };
523 factorial
524 .format(
525 &mut acc,
526 FormatOptions::NONE,
527 &TOO_BIG_NUMBER,
528 &consts,
529 &consts.locales.get("en").unwrap().format,
530 )
531 .unwrap();
532 assert_eq!(acc, "Factorial of 5 is approximately 1.2 × 10^5 \n\n");
533
534 let mut acc = String::new();
535 let factorial = Calculation {
536 value: 5.into(),
537 steps: vec![(1, false)],
538 result: CalculationResult::ApproximateDigits(false, 3.into()),
539 };
540 factorial
541 .format(
542 &mut acc,
543 FormatOptions::NONE,
544 &TOO_BIG_NUMBER,
545 &consts,
546 &consts.locales.get("en").unwrap().format,
547 )
548 .unwrap();
549 assert_eq!(acc, "Factorial of 5 has approximately 3 digits \n\n");
550
551 let mut acc = String::new();
552 let factorial = Calculation {
553 value: 5.into(),
554 steps: vec![(1, false)],
555 result: CalculationResult::Exact(Integer::from(120)),
556 };
557 factorial
558 .format(
559 &mut acc,
560 FormatOptions::FORCE_SHORTEN,
561 &TOO_BIG_NUMBER,
562 &consts,
563 &consts.locales.get("en").unwrap().format,
564 )
565 .unwrap();
566 assert_eq!(acc, "Factorial of 5 is 120 \n\n");
567
568 let consts = Consts::default();
569 let fact = Calculation {
570 value: 10.into(),
571 steps: vec![(3, false)],
572 result: CalculationResult::Exact(280.into()),
573 };
574 let mut s = String::new();
575 fact.format(
576 &mut s,
577 FormatOptions::NONE,
578 &TOO_BIG_NUMBER,
579 &consts,
580 &consts.locales.get("en").unwrap().format,
581 )
582 .unwrap();
583 assert_eq!(s, "Triple-factorial of 10 is 280 \n\n");
584 }
585 #[test]
586 fn test_format_factorial_exact_of_decimal() {
587 let consts = Consts::default();
588 let fact = Calculation {
589 value: Number::Float(Float::with_val(FLOAT_PRECISION, 0.5).into()),
590 steps: vec![(3, false)],
591 result: CalculationResult::Exact(280.into()),
592 };
593 let mut s = String::new();
594 fact.format(
595 &mut s,
596 FormatOptions::NONE,
597 &TOO_BIG_NUMBER,
598 &consts,
599 &consts.locales.get("en").unwrap().format,
600 )
601 .unwrap();
602 assert_eq!(s, "Triple-factorial of 0.5 is approximately 280 \n\n");
603 }
604 #[test]
605 fn test_format_factorial_force_shorten_small() {
606 let consts = Consts::default();
607 let fact = Calculation {
608 value: 10.into(),
609 steps: vec![(3, false)],
610 result: CalculationResult::Exact(280.into()),
611 };
612 let mut s = String::new();
613 fact.format(
614 &mut s,
615 FormatOptions::FORCE_SHORTEN,
616 &TOO_BIG_NUMBER,
617 &consts,
618 &consts.locales.get("en").unwrap().format,
619 )
620 .unwrap();
621 assert_eq!(s, "Triple-factorial of 10 is 280 \n\n");
622 }
623 #[test]
624 fn test_format_factorial_force_shorten_large() {
625 let consts = Consts::default();
626 let fact = Calculation {
627 value: 100.into(),
628 steps: vec![(1, false)],
629 result: CalculationResult::Exact(
630 Integer::from_str("232019615953125000000000000000000").unwrap(),
631 ),
632 };
633 let mut s = String::new();
634 fact.format(
635 &mut s,
636 FormatOptions::NONE,
637 &TOO_BIG_NUMBER,
638 &consts,
639 &consts.locales.get("en").unwrap().format,
640 )
641 .unwrap();
642 assert_eq!(
643 s,
644 "Factorial of 100 is 232019615953125000000000000000000 \n\n"
645 );
646 }
647 #[test]
648 fn test_format_factorial_auto_shorten() {
649 let consts = Consts::default();
650 let fact = Calculation {
651 value: 3249.into(),
652 steps: vec![(1,false)],
653 result: CalculationResult::Exact(
654 Integer::from_str("64123376882765521838840963030568127691878727205333658692200854486404915724268122521695176119279253635876611090137291969570276913721864797759577004121543081865516901512445483449601769965060634861857064173938704305418376606356891014609023859758096597956259938348528946750437026172549655426092377089294607836520057856104816993984697675759579496157280331714452191401635250556082973306115574519424960196953201395066132365440977075392087489735146885581823595966673458107135041749084983583726462930633422893526599365244406644257808664472819062579590372326362859263197427382391737724371130194668325697913147795807287917882271125437793075279592752221056089408917956641344121781056494896664298954714463291743622978314854242079926982168325256172879601086193725507405771749789801611825741625380077209528888301112734777086106637653242107578812065387025070985682845983714635115865868052531038040737170581029905537322341939002838113744745962782070030988628668438192063964391415488312555937962867645737183703289987989371752808444472206166983181218698452231772212240017445423758860236449146575513014084114116542491422920779703202877962388772371297148878539228082497149672927873860981295756607109411429871735683677151117763870227460722732815888175758276344884954699572217509595160880510811349033936358665103889507929390456055037630508759624182491412136058522758117862715726418213812122827526330257260872329993280938592007320434494018056858434839424498517707440601396194949605570023576625190771463278168007414358018195714385208103590743168343592988436427551751120123934640886569178657972642734992568217335134536548423867468448461752994160896483162496996197629537563875663545967947035030506174219867102227347745166308776568259737417457622753953177779829173739659562549005900681020920836575654282170728038645671253311902327576757877160190593437037925134089334990083104974051379653937615220306281104735360028696101767109606466502484676624025302461421267416025443536877684785195571046059926349413586237838043863850610251583618438829618642246353724734656122845609571531588284708710081901687161770748138296656576032229319208279032435434327330035540657667361558905445221013396376775953367966087790302411507662731788873698999846238792500590360394500083923341408008981770566937535640769993694293230514231436990415482012055539596871513163008100690298424743718490882019179903258642028365049142613374709689558800856050749214398290563852574062566904927777093160819034619946818734041081848355062039645388238813669985569729968236449074797273410844560761607809842265309788155248298117938165414543689689754240992067831705834383207309250573018855640140957274364918049364842508738871690383100660359882462072065885517245667353800113210423157317762013988734352812105163694758108035856505778854524789188318600594132430921277654972526820920812190785994887939816114878915385423211996897729890266102145491069991647131611614465930571202528403443141981609375073983780241828798986101030035167624885608168623694530984934856402415662119456280967778213695343026782085453754332973412779641743296676142192492849866399186979810426206090031375249707803725234273693273721779240257093247268647749842459507965336971004339619911629224227060334233904444450352505466038312828689977755744971204784911189528493222070017894145493878499832441010771999957866634720057779638435426615168763950876432375766350648344132624416041623318009761058787995614968607413528076499437020919653085121078341947075546317831737787160036257151637941590867306372647047747729689844801136819011517526975033214302293538465503160183447374945622710595033673253137034231320031041035890947260824330728621640030383790059199531556893062561713763583025693789382680375603227866194301270004745201382665157844733507781537231595412109690534099208802055220457258238249940538761563309465648945964188442431661762589082015016756223358648046396366827537498425276338958018446839292802529780142385903309447658806351362744163752044896322012923382835852429065564336560491610071025646451525782856813152304143339115660276089535216189729579966851236899105440783686498435516601131545345163557980985342246336986737955743799192164259513473592703473521185371309681754246866522812455448210758136891890444056252857117200446002038652603259983493405505521897860879586618028713025173570291196046254005672495787117170419665767607647184551353826735583363126537373726390620854105626900247296291639985561481625404296348051054604042180512892657285238147263167051884385297470314430200590079012539964786079859359747123150407661818942489735756835032462952010303051169237940063644470670372188286551571968317499183600768353941744706305961785518398629201507525785967571188931895809109770264983907551256060144219899670118351808815620474425273993244741972143504134827047237929839845492209316520698259428270901257484509899386082594602760813392081897348940617781009158927227690469330327639146118508499255466535663882163793101115885899345523332216762566667486023534622719542192198250458735391090024294254053186440646305309340840685145289223131431157156390489399333752075193525158125680201419183806547205312873264380358849214095835479613319512867197427682723250079990981586869733293245764804577570764831692705888317075918673294669326798053736223321604803330275717540789920865913177228227111643923604665959921096208765542277777829882980225810940866410254096689483571105776785837917708633884075471298045453873223073787369262426626913405098535070631297346400765749139515252242178612533747493270131589184346851060077512732273563896936880596142362061341020737937605198462006142952423931616201569440226926787162077801883794168906567939864710313203688516686488132607069944238278930371283198545637735863991249832218463680910774912311493673518088306563853170521159963238305666024221618323515872866318153226269712890565361382209276094137857215708859605439920538254391240145615109307534437972388439697355227469268959991826344643967606862639207957142695059497774782782862380576527665249011786632721781635858363134217267161265609789721847126531549373639397319541419174824349828634414533913160986280670700117904134971824878639490677063427559640621162799757094469987184056964512589036737188936656494184932005003301076625555129466247988108160104882718140259576746243025950653945267030862681712132414998384138315991964228278130346276982182371619123375659027762342810200791337975076096607162500887202849331840711439619934443487228446573730294798389422723901661778354768525095757656920903185278358954945675520361768231577076750321654682566951617894418024879897723932943778739392625374786945631297844013055183788373235917906391604745846654356151085578611880261515860397623972021392725059655970516681719822949498069366408864396412928494605832710960284204937215373010567096882590065428759248976242854170628853902061231484918006271406155707387649451852150396381227895427254475130432845540997751264574249884576973754475522081887586009543117655192564603663203594121977491966995919938707026254622729082886656923266824175261927609862131917883084745112234024557978747561458733390353402381353061864973111801478933098174668694254024372053350135966105816774315863351432700501507214833910835095241116220945368287364828423032249431110250529198415073098056537298790818802403747860478015395740166511031245261193793854201285682331906071528112005073514650997116494101706639070013374677115821301361236988511929513457351929738018793684759539098410509535113338894579685309152120362751957602730649344150813012563246391457667149097699631546631367291707994927436193366185835774355812730356484690902974319470019544218388669048171395399380611906621586431005917959473642252829970939300283923684023821586277795276767391621510747281802893209607052311085173753725616353413592446675522238914835135290803927878090361225614843018882327106532840756094139114333346621153175254833577042328095480536834801026590432360931424294133543336408702705440236553526213058195627059654976746315636170233701887454392139871178240463495036735780991998499617099173145932919728906603992606395026374552882029156921168342421270810263586384930758466962518032019544198713384832174173447126633137813741748004660781750992387224960402183367639878315847417040125065349322346833085734948541674565230896990919815801676540094611430605654337096768783494147476599630304276589463660992695730097812987784061106253993478908686689107637583574009574525664941872851644555317421340687668414081763994364249671165252652825318436095248164540239487724330276498957490699548343852181838068378612444949106850962864407345130509165857647406496109100001533123176834579856292423765079015513705518869769002090306548513909235083737585930276738943593954668225536658208962591163051195501324651032924378645456520478535714079874404144783894706654731307268880764144813567558473827034967105368425271973138213726718055181321006250745589786136935583735915890517993411416086214277469794370188740010736604373520529352427775875772577651690552630708696044935360500197728514057299685757816479040563926362665221456966339198099627395349937057349473111399655105587183432516687910987518148931239145857422059143761070545360054386871218955184209375241453611589548642653321253873363792347807426924575722280463634222994099258528815002881358362491008896204800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000").unwrap()
655 ),
656 };
657 let mut s = String::new();
658 fact.format(
659 &mut s,
660 FormatOptions::NONE,
661 &TOO_BIG_NUMBER,
662 &consts,
663 &consts.locales.get("en").unwrap().format,
664 )
665 .unwrap();
666 assert_eq!(
667 s,
668 "Factorial of 3249 is roughly 6.412337688276552183884096303057 × 10^10000 \n\n"
669 );
670 }
671 #[test]
672 fn test_format_factorial_chain() {
673 let consts = Consts::default();
674 let fact = Calculation {
675 value: 5.into(),
676 steps: vec![(3, false), (1, false)],
677 result: CalculationResult::Exact(3628800.into()),
678 };
679 let mut s = String::new();
680 fact.format(
681 &mut s,
682 FormatOptions::NONE,
683 &TOO_BIG_NUMBER,
684 &consts,
685 &consts.locales.get("en").unwrap().format,
686 )
687 .unwrap();
688 assert_eq!(s, "Factorial of triple-factorial of 5 is 3628800 \n\n");
689 }
690 #[test]
691 fn test_format_factorial_negative() {
692 let consts = Consts::default();
693 let fact = Calculation {
694 value: 0.into(),
695 steps: vec![(1, true)],
696 result: CalculationResult::Exact(3628800.into()),
697 };
698 let mut s = String::new();
699 fact.format(
700 &mut s,
701 FormatOptions::NONE,
702 &TOO_BIG_NUMBER,
703 &consts,
704 &consts.locales.get("en").unwrap().format,
705 )
706 .unwrap();
707 assert_eq!(s, "Negative factorial of 0 is 3628800 \n\n");
708 }
709 #[test]
710 fn test_format_approximate_factorial() {
711 let consts = Consts::default();
712 let fact = Calculation {
713 value: 0.into(),
714 steps: vec![(1, false)],
715 result: CalculationResult::Approximate(
716 Float::with_val(FLOAT_PRECISION, Float::parse("2.83947").unwrap()).into(),
717 10043.into(),
718 ),
719 };
720 let mut s = String::new();
721 fact.format(
722 &mut s,
723 FormatOptions::NONE,
724 &TOO_BIG_NUMBER,
725 &consts,
726 &consts.locales.get("en").unwrap().format,
727 )
728 .unwrap();
729 assert_eq!(s, "Factorial of 0 is approximately 2.83947 × 10^10043 \n\n");
730 }
731 #[test]
732 fn test_format_approximate_digits_factorial() {
733 let consts = Consts::default();
734 let fact = Calculation {
735 value: 0.into(),
736 steps: vec![(1, false)],
737 result: CalculationResult::ApproximateDigits(false, 10043394.into()),
738 };
739 let mut s = String::new();
740 fact.format(
741 &mut s,
742 FormatOptions::NONE,
743 &TOO_BIG_NUMBER,
744 &consts,
745 &consts.locales.get("en").unwrap().format,
746 )
747 .unwrap();
748 assert_eq!(s, "Factorial of 0 has approximately 10043394 digits \n\n");
749 }
750 #[test]
751 fn test_format_complex_infinity_factorial() {
752 let consts = Consts::default();
753 let fact = Calculation {
754 value: 0.into(),
755 steps: vec![(1, false)],
756 result: CalculationResult::ComplexInfinity,
757 };
758 let mut s = String::new();
759 fact.format(
760 &mut s,
761 FormatOptions::NONE,
762 &TOO_BIG_NUMBER,
763 &consts,
764 &consts.locales.get("en").unwrap().format,
765 )
766 .unwrap();
767 assert_eq!(s, "Factorial of 0 is ∞\u{0303} \n\n");
768 }
769 #[test]
770 fn test_format_digits_tower() {
771 let consts = Consts::default();
772 let fact = Calculation {
773 value: 0.into(),
774 steps: vec![(1, false)],
775 result: CalculationResult::ApproximateDigitsTower(false, false, 9.into(), 10375.into()),
776 };
777 let mut s = String::new();
778 fact.format(
779 &mut s,
780 FormatOptions::NONE,
781 &TOO_BIG_NUMBER,
782 &consts,
783 &consts.locales.get("en").unwrap().format,
784 )
785 .unwrap();
786 assert_eq!(
787 s,
788 "Factorial of 0 has on the order of 10^(10\\^10\\^10\\^10\\^10\\^10\\^10\\^10\\^(10375\\)) digits \n\n"
789 );
790 }
791 #[test]
792 fn test_format_digits_tower_negative() {
793 let consts = Consts::default();
794 let fact = Calculation {
795 value: 0.into(),
796 steps: vec![(1, false)],
797 result: CalculationResult::ApproximateDigitsTower(false, true, 9.into(), 10375.into()),
798 };
799 let mut s = String::new();
800 fact.format(
801 &mut s,
802 FormatOptions::NONE,
803 &TOO_BIG_NUMBER,
804 &consts,
805 &consts.locales.get("en").unwrap().format,
806 )
807 .unwrap();
808 assert_eq!(
809 s,
810 "Factorial of 0 has on the order of -10^(10\\^10\\^10\\^10\\^10\\^10\\^10\\^10\\^(10375\\)) digits \n\n"
811 );
812 }
813 #[test]
814 fn test_format_digits_tower_tet() {
815 let consts = Consts::default();
816 let fact = Calculation {
817 value: 0.into(),
818 steps: vec![(1, false), (1, false)],
819 result: CalculationResult::ApproximateDigitsTower(false, false, 9.into(), 10375.into()),
820 };
821 let mut s = String::new();
822 fact.format(
823 &mut s,
824 FormatOptions::AGRESSIVE_SHORTEN,
825 &TOO_BIG_NUMBER,
826 &consts,
827 &consts.locales.get("en").unwrap().format,
828 )
829 .unwrap();
830 assert_eq!(s, "All that of 0 has on the order of ^(10)10 digits \n\n");
831 }
832 #[test]
833 fn test_format_gamma() {
834 let consts = Consts::default();
835 let fact = Calculation {
836 value: Number::Float(
837 Float::with_val(FLOAT_PRECISION, Float::parse("9.2").unwrap()).into(),
838 ),
839 steps: vec![(1, false)],
840 result: CalculationResult::Float(
841 Float::with_val(FLOAT_PRECISION, Float::parse("893.83924421").unwrap()).into(),
842 ),
843 };
844 let mut s = String::new();
845 fact.format(
846 &mut s,
847 FormatOptions::NONE,
848 &TOO_BIG_NUMBER,
849 &consts,
850 &consts.locales.get("en").unwrap().format,
851 )
852 .unwrap();
853 assert_eq!(s, "Factorial of 9.2 is approximately 893.83924421 \n\n");
854 }
855 #[test]
856 fn test_format_gamma_fallback() {
857 let consts = Consts::default();
858 let fact = Calculation {
859 value: Number::Float(Float::with_val(FLOAT_PRECISION, 0).into()),
860 steps: vec![(1, false)],
861 result: {
862 let mut m = Float::with_val(FLOAT_PRECISION, f64::MAX);
863 m.next_up();
864 CalculationResult::Float(m.into())
865 },
866 };
867 let mut s = String::new();
868 fact.format(
869 &mut s,
870 FormatOptions::NONE,
871 &TOO_BIG_NUMBER,
872 &consts,
873 &consts.locales.get("en").unwrap().format,
874 )
875 .unwrap();
876 assert_eq!(
877 s,
878 "Factorial of 0 is approximately 1.797693134862315708145274237317 × 10^308 \n\n"
879 );
880 }
881 #[test]
882 fn test_format_approximate_factorial_shorten() {
883 let consts = Consts::default();
884 let fact = Calculation {
885 value: Number::Exact(
886 Integer::from_str("2018338437429423744923849374833232131").unwrap(),
887 ),
888 steps: vec![(1, false)],
889 result: CalculationResult::Approximate(
890 Float::with_val(FLOAT_PRECISION, Float::parse("2.8394792834").unwrap()).into(),
891 Integer::from_str("10094283492304894983443984102489842984271").unwrap(),
892 ),
893 };
894 let mut s = String::new();
895 fact.format(
896 &mut s,
897 FormatOptions::FORCE_SHORTEN,
898 &TOO_BIG_NUMBER,
899 &consts,
900 &consts.locales.get("en").unwrap().format,
901 )
902 .unwrap();
903 assert_eq!(
904 s,
905 "Factorial of roughly 2.018338437429423744923849374833 × 10^36 is approximately 2.8394792834 × 10^(1.009428349230489498344398410249 × 10^40) \n\n"
906 );
907 }
908 #[test]
909 fn test_format_approximate_digits_factorial_shorten() {
910 let consts = Consts::default();
911 let fact = Calculation {
912 value: Number::Exact(
913 Integer::from_str("2313820948092579283573259490834298719").unwrap(),
914 ),
915 steps: vec![(1, false)],
916 result: CalculationResult::ApproximateDigits(
917 false,
918 Integer::from_str("9842371208573508275237815084709374240128347012847").unwrap(),
919 ),
920 };
921 let mut s = String::new();
922 fact.format(
923 &mut s,
924 FormatOptions::FORCE_SHORTEN,
925 &TOO_BIG_NUMBER,
926 &consts,
927 &consts.locales.get("en").unwrap().format,
928 )
929 .unwrap();
930 assert_eq!(
931 s,
932 "Factorial of roughly 2.313820948092579283573259490834 × 10^36 has approximately 9.842371208573508275237815084709 × 10^48 digits \n\n"
933 );
934 }
935 #[test]
936 fn test_format_digits_tower_shorten() {
937 let consts = Consts::default();
938 let fact = Calculation {
939 value: Number::Exact(
940 Integer::from_str("13204814708471087502685784603872164320053271").unwrap(),
941 ),
942 steps: vec![(1, false)],
943 result: CalculationResult::ApproximateDigitsTower(
944 false,
945 false,
946 9.into(),
947 Integer::from_str("7084327410873502875032857120358730912469148632").unwrap(),
948 ),
949 };
950 let mut s = String::new();
951 fact.format(
952 &mut s,
953 FormatOptions::FORCE_SHORTEN,
954 &TOO_BIG_NUMBER,
955 &consts,
956 &consts.locales.get("en").unwrap().format,
957 )
958 .unwrap();
959 assert_eq!(
960 s,
961 "Factorial of roughly 1.320481470847108750268578460387 × 10^43 has on the order of 10^(10\\^10\\^10\\^10\\^10\\^10\\^10\\^10\\^(7.084327410873502875032857120359 × 10^45\\)) digits \n\n"
962 );
963 }
964 #[test]
965 fn test_format_huge() {
966 let consts = Consts::default();
967 let fact = Calculation {
968 value: 0.into(),
969 steps: vec![(1, false)],
970 result: CalculationResult::Exact({
971 let mut r = Float::with_val(FLOAT_PRECISION, crate::rug::float::Special::Infinity);
972 r.next_down();
973 r.to_integer().unwrap()
974 }),
975 };
976 let mut s = String::new();
977 fact.format(
978 &mut s,
979 FormatOptions::NONE,
980 &TOO_BIG_NUMBER,
981 &consts,
982 &consts.locales.get("en").unwrap().format,
983 )
984 .unwrap();
985 assert_eq!(
986 s,
987 "Factorial of 0 is roughly 2.098578716467387692404358116884 × 10^323228496 \n\n"
988 );
989 }
990
991 #[test]
992 fn test_tower_value_with_one_top() {
993 let consts = Consts::default();
994 let fact = Calculation {
995 value: 0.into(),
996 steps: vec![(1, false)],
997 result: CalculationResult::ApproximateDigitsTower(false, false, 4.into(), 1.into()),
998 };
999 let mut s = String::new();
1000 fact.format(
1001 &mut s,
1002 FormatOptions::NONE,
1003 &TOO_BIG_NUMBER,
1004 &consts,
1005 &consts.locales.get("en").unwrap().format,
1006 )
1007 .unwrap();
1008 assert_eq!(s, "Factorial of 0 has on the order of ^(4)10 digits \n\n");
1009 }
1010
1011 #[test]
1012 fn test_calculation_is_approximate() {
1013 let c1 = Calculation {
1014 value: 0.into(),
1015 steps: vec![],
1016 result: CalculationResult::Approximate(
1017 Float::with_val(FLOAT_PRECISION, 2.0).into(),
1018 1.into(),
1019 ),
1020 };
1021 assert!(c1.is_approximate());
1022 let c2 = Calculation {
1023 value: 0.into(),
1024 steps: vec![],
1025 result: CalculationResult::Exact(1.into()),
1026 };
1027 assert!(!c2.is_approximate());
1028 }
1029
1030 #[test]
1031 fn test_calculation_is_rounded() {
1032 let c1 = Calculation {
1033 value: Number::Float(Float::with_val(FLOAT_PRECISION, 1.23).into()),
1034 steps: vec![],
1035 result: CalculationResult::Approximate(
1036 Float::with_val(FLOAT_PRECISION, 0.0).into(),
1037 0.into(),
1038 ),
1039 };
1040 assert!(c1.is_rounded());
1041 let c2 = Calculation {
1042 value: Number::Float(Float::with_val(FLOAT_PRECISION, 1.23).into()),
1043 steps: vec![],
1044 result: CalculationResult::Float(Float::with_val(FLOAT_PRECISION, 1.23).into()),
1045 };
1046 assert!(!c2.is_rounded());
1047 let c3 = Calculation {
1048 value: 1.into(),
1049 steps: vec![],
1050 result: CalculationResult::Exact(1.into()),
1051 };
1052 assert!(!c3.is_rounded());
1053 }
1054
1055 #[test]
1056 fn test_is_too_long() {
1057 let small = Calculation {
1058 value: 1.into(),
1059 steps: vec![],
1060 result: CalculationResult::Exact(1.into()),
1061 };
1062 assert!(!small.is_too_long(&TOO_BIG_NUMBER));
1063 let big = Calculation {
1064 value: 1.into(),
1065 steps: vec![],
1066 result: CalculationResult::Exact((*TOO_BIG_NUMBER).clone() + 1),
1067 };
1068 assert!(big.is_too_long(&TOO_BIG_NUMBER));
1069 let fl = Calculation {
1070 value: 1.into(),
1071 steps: vec![],
1072 result: CalculationResult::Float(Float::with_val(FLOAT_PRECISION, 1.0).into()),
1073 };
1074 assert!(!fl.is_too_long(&TOO_BIG_NUMBER));
1075 }
1076
1077 #[test]
1078 fn test_number_decimals_scientific_respected() {
1079 let mut consts = Consts::default();
1080 consts.number_decimals_scientific = 10;
1081 let mut acc = String::new();
1082 CalculationResult::Exact(Integer::u_pow_u(10, 1000).complete() * 498149837492347328u64)
1083 .format(
1084 &mut acc,
1085 &mut false,
1086 FormatOptions::FORCE_SHORTEN,
1087 false,
1088 &consts,
1089 &locale::NumFormat { decimal: '.' },
1090 )
1091 .unwrap();
1092 assert_eq!(acc, "4.9814983749 × 10^1017");
1093 let mut acc = String::new();
1094 CalculationResult::Approximate(
1095 Float::with_val(FLOAT_PRECISION, 4.98149837492347328f64).into(),
1096 1017.into(),
1097 )
1098 .format(
1099 &mut acc,
1100 &mut false,
1101 FormatOptions::FORCE_SHORTEN,
1102 false,
1103 &consts,
1104 &locale::NumFormat { decimal: '.' },
1105 )
1106 .unwrap();
1107 assert_eq!(acc, "4.9814983749 × 10^(1017)");
1108 consts.number_decimals_scientific = 50;
1109 let mut acc = String::new();
1110 CalculationResult::Exact(
1111 Integer::u_pow_u(10, 1000).complete() * 49814983749234732849839849898438493843u128,
1112 )
1113 .format(
1114 &mut acc,
1115 &mut false,
1116 FormatOptions::FORCE_SHORTEN,
1117 false,
1118 &consts,
1119 &locale::NumFormat { decimal: '.' },
1120 )
1121 .unwrap();
1122 assert_eq!(acc, "4.9814983749234732849839849898438493843 × 10^1037");
1123 let mut acc = String::new();
1124 CalculationResult::Approximate(
1125 Float::with_val(
1126 FLOAT_PRECISION,
1127 Float::parse("4.9814983749234732849839849898438493843").unwrap(),
1128 )
1129 .into(),
1130 1037.into(),
1131 )
1132 .format(
1133 &mut acc,
1134 &mut false,
1135 FormatOptions::FORCE_SHORTEN,
1136 false,
1137 &consts,
1138 &locale::NumFormat { decimal: '.' },
1139 )
1140 .unwrap();
1141 assert_eq!(acc, "4.9814983749234732849839849898438493843 × 10^(1037)");
1142 }
1143 #[test]
1144 fn test_format_float() {
1145 let mut consts = Consts::default();
1146 let mut acc = String::new();
1147 format_float(
1148 &mut acc,
1149 &Float::with_val(
1150 FLOAT_PRECISION,
1151 Float::parse("0.999999999999999999999999999999999").unwrap(),
1152 ),
1153 &consts,
1154 )
1155 .unwrap();
1156 assert_eq!(acc, "1");
1157 let mut acc = String::new();
1158 format_float(
1159 &mut acc,
1160 &Float::with_val(
1161 FLOAT_PRECISION,
1162 Float::parse("0.000000000000000000000000000000009").unwrap(),
1163 ),
1164 &consts,
1165 )
1166 .unwrap();
1167 assert_eq!(acc, "9 × 10^-33");
1168 consts.number_decimals_scientific = 2;
1169 acc.clear();
1170 format_float(
1171 &mut acc,
1172 &Float::with_val(FLOAT_PRECISION, Float::parse("0.10").unwrap()),
1173 &consts,
1174 )
1175 .unwrap();
1176 assert_eq!(acc, "0.1");
1177
1178 let consts = Consts::default();
1179 acc.clear();
1180 format_float(
1181 &mut acc,
1182 &Float::with_val(FLOAT_PRECISION, Float::parse("6.631537423e-34").unwrap()),
1183 &consts,
1184 )
1185 .unwrap();
1186 assert_eq!(acc, "6.631537423 × 10^-34");
1187 let consts = Consts::default();
1188 acc.clear();
1189 format_float(
1190 &mut acc,
1191 &Float::with_val(FLOAT_PRECISION, Float::parse("6.631537423e34").unwrap()),
1192 &consts,
1193 )
1194 .unwrap();
1195 assert_eq!(acc, "6.631537423 × 10^34");
1196 }
1197}