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