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