break_eternity/
lib.rs

1#![warn(missing_docs)]
2#![crate_name = "break_eternity"]
3
4//! A numerical library to represent numbers as large as 10^^1e308 and as 'small' as 10^-(10^^1e308).
5//!
6//! # Examples
7//!
8//! ```
9//! use break_eternity::Decimal;
10//!
11//! let a = Decimal::from_number(1.0);
12//! let b = Decimal::from_number(2.0);
13//!
14//! let c = a + b;
15//! assert_eq!(c, Decimal::from_number(3.0));
16//! ```
17
18use custom_error::custom_error;
19use std::{
20    convert::{TryFrom, TryInto},
21    fmt::{Display, LowerExp, UpperExp},
22    num::ParseFloatError,
23    ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Rem, RemAssign, Sub, SubAssign},
24};
25
26custom_error! {
27    /// Error type for all errors in this crate.
28    pub BreakEternityError
29        /// An error that occurs when f_gamma and lambertw fails to converge a number (more than 100 iterations)
30        IterationFailedConverging {
31            /// The number that failed to converge
32            z: f64
33        } = "Iteration failed to converge: {z}",
34        /// An error that occurs when a String cannot be parsed to a Decimal
35        ParseError {
36            /// The string that failed to parse
37            parsed: String,
38            /// The error that occurred
39            error: ParseFloatError
40        } = "Error while parsing \"{parsed}\": {error}",
41        /// An error that occurs when lambertw is called with a number less than -1
42        LambertWError = "lambertw is undefined for results < -1"
43}
44
45type Number = f64;
46
47/// Maximum number of digits of precision to assume in a float
48pub const MAX_FLOAT_PRECISION: usize = 17;
49/// Exponent limit to increase a layer (9e15 is about the largest safe number)
50///
51/// If above this value, increase a layer
52pub const EXPONENT_LIMIT: Number = 9e15;
53/// Layer reduction threshold
54///
55/// If below this value, reduce a layer. Approximately 15.954.
56pub const LAYER_REDUCTION_THRESHOLD: Number = 15.954242509439325;
57/// At layer 0, smaller non-zero numbers than this become layer 1 numbers with negative mag.
58///
59/// After that the pattern continues as normal.
60pub const FIRST_NEG_LAYER: Number = 1_f64 / 9e15;
61/// Largest exponent that can appear in a number.
62///
63/// Not all mantissas are valid here.
64pub const NUMBER_EXP_MAX: i32 = 308;
65/// Smallest exponent that can appear in a number.
66///
67/// Not all mantissas are valid here.
68pub const NUMBER_EXP_MIN: i32 = -324;
69/// Amount of Es that will be printed in a string representation of a Decimal.
70pub const MAX_ES_IN_A_ROW: u64 = 5;
71/// Maximum number powers of 10 that will be cached.
72pub const MAX_POWERS_OF_TEN: usize = (NUMBER_EXP_MAX - NUMBER_EXP_MIN + 1) as usize;
73/// 2*PI
74pub const TWO_PI: f64 = std::f64::consts::TAU;
75/// exp(-1)
76pub const EXPN1: f64 = 0.36787944117144233;
77/// W(1, 0)
78pub const OMEGA: f64 = 0.5671432904097838;
79
80lazy_static::lazy_static! {
81    /// A cache of powers of 10 up to NUMBER_EXP_MAX.
82    static ref POWERS_OF_TEN: Vec<f64> = {
83        let mut powers_of_ten: Vec<f64> = Vec::new();
84        for i in (NUMBER_EXP_MIN + 1) ..= NUMBER_EXP_MAX {
85            powers_of_ten.push(format!("1e{}", i).parse().unwrap());
86        }
87        powers_of_ten
88    };
89    /// A flag if commas in a String representation should be ignored
90    static ref IGNORE_COMMAS: bool = true;
91    /// A flag if commas are used as decimal points instead.
92    static ref COMMAS_ARE_DECIMAL_POINTS: bool = false;
93}
94
95/// Returns the sign of the number.
96///
97/// This implementation is different from f64::signum() because it returns 0 for 0.0 and NaN.
98pub fn sign(num: f64) -> i8 {
99    if num.is_nan() {
100        return 0;
101    }
102
103    if num == 0.0 {
104        return 0;
105    }
106
107    if num.is_infinite() {
108        return if num.is_sign_positive() { 1 } else { -1 };
109    }
110
111    if num > 0.0 {
112        return 1;
113    }
114
115    -1
116}
117
118/// Formats the given number to the given number of significant digits.
119pub fn to_fixed(num: f64, places: i32) -> String {
120    format!("{:.*}", places.try_into().unwrap(), num)
121}
122
123fn power_of_10(exp: i32) -> Number {
124    POWERS_OF_TEN[(exp + 323) as usize]
125}
126
127/// Truncates the given number to the given number of significant digits and rounds, if necessary.
128pub fn decimal_places(num: Number, places: i32) -> Number {
129    let len = places as f64 + 1_f64;
130    let num_digits = num.abs().log10().ceil();
131    let rounded = (num * 10_f64.powf(len - num_digits)).round() * 10_f64.powf(num_digits - len);
132    to_fixed(rounded, (len - num_digits).max(0_f64) as i32)
133        .parse()
134        .unwrap()
135}
136
137fn f_maglog10(num: Number) -> Number {
138    sign(num) as f64 * num.abs().log10()
139}
140
141fn f_gamma(mut num: Number) -> Number {
142    if !num.is_finite() {
143        return num;
144    }
145
146    if num < -50.0 {
147        if (num - num.trunc()).abs() < 1e-10 {
148            return Number::NEG_INFINITY;
149        }
150        return 0.0;
151    }
152
153    let mut scal1 = 1.0;
154    while num < 10.0 {
155        scal1 *= num;
156        num += 1.0;
157    }
158
159    num += 1.0;
160    let mut l = 0.9189385332046727;
161    l += (num + 0.5) * num.ln();
162    l -= num;
163    let num2 = num * num;
164    let mut num_p = num;
165    l += 1.0 / (12.0 * num_p);
166    num_p *= num2;
167    l += 1.0 / (360.0 * num_p);
168    num_p *= num2;
169    l += 1.0 / (1260.0 * num_p);
170    num_p *= num2;
171    l += 1.0 / (1680.0 * num_p);
172    num_p *= num2;
173    l += 1.0 / (1188.0 * num_p);
174    num_p *= num2;
175    l += 691.0 / (360360.0 * num_p);
176    num_p *= num2;
177    l += 7.0 / (1092.0 * num_p);
178    num_p *= num2;
179    l += 3617.0 / (122400.0 * num_p);
180
181    l.exp() / scal1
182}
183
184fn f_lambertw(z: Number, mut tol: Option<Number>) -> Result<Number, BreakEternityError> {
185    if tol.is_none() {
186        tol = Some(1e-10);
187    }
188
189    let mut w;
190    let mut wn;
191
192    if !z.is_finite() {
193        return Ok(z);
194    }
195
196    if z == 0.0 {
197        return Ok(z);
198    }
199
200    if (z - 1.0).abs() < 1e-10 {
201        return Ok(OMEGA);
202    }
203
204    if z < 10.0 {
205        w = 0.0;
206    } else {
207        w = z.ln() - z.ln().ln();
208    }
209
210    for _ in 0..100 {
211        wn = (z * (-w).exp() + w * w) / (w + 1.0);
212        if (wn - w).abs() < tol.unwrap() * wn.abs() {
213            return Ok(wn);
214        } else {
215            w = wn;
216        }
217    }
218
219    Err(BreakEternityError::IterationFailedConverging { z })
220}
221
222fn d_lambertw(z: Decimal, mut tol: Option<Number>) -> Result<Decimal, BreakEternityError> {
223    if tol.is_none() {
224        tol = Some(1e-10);
225    }
226
227    let mut w;
228    let mut ew;
229    let mut wewz;
230    let mut wn;
231
232    if !z.mag.is_finite() {
233        return Ok(z);
234    }
235
236    if z == Decimal::zero() {
237        return Ok(z);
238    }
239
240    if z == Decimal::one() {
241        return Ok(Decimal::from_number(OMEGA));
242    }
243
244    w = z.ln();
245
246    // Halley's method
247    for _ in 0..100 {
248        ew = (-w).exp();
249        wewz = w - z * ew;
250        wn = w - wewz
251            / (w + Decimal::from_number(1.0)
252                - (w + Decimal::from_number(2.0)) * wewz
253                    / (Decimal::from_number(2.0) * w + Decimal::from_number(2.0)));
254
255        if (wn - w).abs() < Decimal::from_number(tol.unwrap()) * wn.abs() {
256            return Ok(wn);
257        } else {
258            w = wn;
259        }
260    }
261
262    Err(BreakEternityError::IterationFailedConverging { z: z.to_number() })
263}
264
265/// A Decimal number that can represent numbers as large as 10^^1e308 and as 'small' as 10^-(10^^1e308).
266#[derive(Clone, Copy, Debug, Default)]
267#[cfg_attr(
268    feature = "godot",
269    derive(gdnative::prelude::FromVariant, gdnative::prelude::ToVariant)
270)]
271pub struct Decimal {
272    /// Sign of the Decimal. 1 for positive, -1 for negative.
273    pub sign: i8,
274    /// Layer of magnitude.
275    pub layer: i64,
276    /// Magnitude of the Decimal.
277    pub mag: Number,
278}
279
280impl Decimal {
281    /// Creates a new Decimal
282    ///
283    /// This does not normalize the Decimal, use [Decimal::from_components] for automatic normalization.
284    pub fn new(sign: i8, layer: i64, mag: Number) -> Decimal {
285        Decimal { sign, layer, mag }
286    }
287
288    /// Returns the mantissa of the Decimal
289    pub fn mantissa(&self) -> Number {
290        if self.sign == 0 {
291            return 0.0;
292        }
293
294        if self.layer == 0 {
295            let exp = self.mag.abs().log10().floor();
296            // handle special case 5e-324
297            let man = if (self.mag - 5e-324).abs() < 1e-10 {
298                5.0
299            } else {
300                self.mag / power_of_10(exp as i32)
301            };
302
303            return self.sign as f64 * man;
304        }
305
306        if self.layer == 1 {
307            let residue = self.mag - self.mag.floor();
308            return self.sign as f64 * 10.0_f64.powf(residue);
309        }
310
311        self.sign as f64
312    }
313
314    /// Sets the mantissa of the Decimal
315    pub fn set_mantissa(&mut self, m: Number) {
316        if self.layer <= 2 {
317            self.set_from_mantissa_exponent(m, self.layer as f64);
318        } else {
319            // this mantissa isn't meaningful
320            self.sign = sign(m);
321            if self.sign == 0 {
322                self.layer = 0;
323                self.set_exponent(0.0);
324            }
325        }
326    }
327
328    /// Returns the exponent of the Decimal
329    pub fn exponent(&self) -> Number {
330        if self.sign == 0 {
331            return 0.0;
332        }
333
334        if self.layer == 0 {
335            return self.mag.log10().floor();
336        }
337
338        if self.layer == 1 {
339            return self.mag.floor();
340        }
341
342        if self.layer == 2 {
343            return (sign(self.mag) as f64 * self.mag.abs().powf(10.0)).floor();
344        }
345
346        self.mag * Number::INFINITY
347    }
348
349    /// Sets the exponent of the Decimal
350    pub fn set_exponent(&mut self, e: Number) {
351        self.set_from_mantissa_exponent(self.mantissa(), e);
352    }
353
354    /// Returns the sign of the Decimal
355    pub fn sign(&self) -> i8 {
356        self.sign
357    }
358
359    /// Sets the sign of the Decimal
360    pub fn set_sign(&mut self, s: i8) {
361        if s == 0 {
362            self.sign = 0;
363            self.layer = 0;
364            self.mag = 0.0;
365        } else {
366            self.sign = s;
367        }
368    }
369
370    /// Returns the layer of the Decimal
371    pub fn layer(&self) -> i64 {
372        self.layer
373    }
374
375    /// Sets the layer of the Decimal
376    pub fn set_layer(&mut self, l: i64) {
377        self.layer = l;
378    }
379
380    /// Returns the magnitude of the Decimal
381    pub fn mag(&self) -> Number {
382        self.mag
383    }
384
385    /// Sets the magnitude of the Decimal
386    pub fn set_mag(&mut self, m: Number) {
387        self.mag = m;
388    }
389
390    /// Creates a Decimal from a sign, a layer and a magnitude
391    ///
392    /// This function normalizes the inputs
393    pub fn from_components(sign: i8, layer: i64, mag: Number) -> Decimal {
394        Decimal::default().set_from_components(sign, layer, mag)
395    }
396
397    /// Creates a Decimal from a sign, a layer and a magnitude
398    ///
399    /// This function does not normalize the inputs
400    pub fn from_components_no_normalize(sign: i8, layer: i64, mag: Number) -> Decimal {
401        Decimal::default().set_from_components_no_normalize(sign, layer, mag)
402    }
403
404    /// Creates a Decimal from a mantissa and an exponent
405    ///
406    /// This function normalizes the inputs
407    pub fn from_mantissa_exponent(m: Number, e: Number) -> Decimal {
408        Decimal::default().set_from_mantissa_exponent(m, e)
409    }
410
411    /// Creates a Decimal from a mantissa and an exponent
412    ///
413    /// This function does not normalize the inputs
414    pub fn from_mantissa_exponent_no_normalize(m: Number, e: Number) -> Decimal {
415        Decimal::default().set_from_mantissa_exponent_no_normalize(m, e)
416    }
417
418    /// Creates a Decimal from a number (f64)
419    pub fn from_number(n: Number) -> Decimal {
420        if n.is_nan() {
421            return Decimal::nan();
422        }
423
424        if n.is_infinite() && n.is_sign_positive() {
425            return Decimal::inf();
426        }
427
428        if n.is_infinite() && n.is_sign_negative() {
429            return Decimal::neg_inf();
430        }
431
432        Decimal::default().set_from_number(n)
433    }
434
435    /// Normalizes the Decimal as follows:
436    ///
437    /// * Whenever we are partially 0 (sign is 0 or mag and layer is 0), make it fully 0.
438    /// * Whenever we are at or hit layer 0, extract sign from negative mag.
439    /// * If layer === 0 and mag < FIRST_NEG_LAYER (1/9e15), shift to 'first negative layer' (add layer, log10 mag).
440    /// * While abs(mag) > EXP_LIMIT (9e15), layer += 1, mag = maglog10(mag).
441    /// * While abs(mag) < LAYER_DOWN (15.954) and layer > 0, layer -= 1, mag = pow(10, mag).
442    /// * When we're done, all of the following should be true OR one of the numbers is not finite OR layer is not an integer (error state):
443    ///     * Any 0 is totally zero (0, 0, 0).
444    ///     * Anything layer 0 has mag 0 OR mag > 1/9e15 and < 9e15.
445    ///     * Anything layer 1 or higher has abs(mag) >= 15.954 and < 9e15.
446    /// * We will assume in calculations that all Decimals are either erroneous or satisfy these criteria. (Otherwise: Garbage in, garbage out.)
447    pub fn normalize(&mut self) -> Decimal {
448        if self.sign == 0 || (self.mag == 0.0 && self.layer == 0) {
449            self.sign = 0;
450            self.layer = 0;
451            self.mag = 0.0;
452            return *self;
453        }
454
455        if self.layer == 0 && self.mag < 0.0 {
456            self.mag = -self.mag;
457            self.sign = -self.sign;
458        }
459
460        if self.layer == 0 && self.mag < FIRST_NEG_LAYER {
461            self.layer += 1;
462            self.mag = self.mag.log10();
463            return *self;
464        }
465
466        let mut abs_mag = self.mag.abs();
467        let mut sign_mag = sign(self.mag) as f64;
468
469        if abs_mag >= EXPONENT_LIMIT {
470            self.layer += 1;
471            self.mag = sign_mag * abs_mag.log10();
472            return *self;
473        }
474
475        while abs_mag < LAYER_REDUCTION_THRESHOLD && self.layer > 0 {
476            self.layer -= 1;
477            if self.layer == 0 {
478                self.mag = 10.0_f64.powf(self.mag);
479            } else {
480                self.mag = sign_mag * 10.0_f64.powf(abs_mag);
481                abs_mag = self.mag.abs();
482                sign_mag = sign(self.mag) as f64;
483            }
484        }
485
486        if self.layer == 0 {
487            if self.mag < 0.0 {
488                self.mag = -self.mag;
489                self.sign = -self.sign;
490            } else if self.mag == 0.0 {
491                self.sign = 0;
492            }
493        }
494
495        *self
496    }
497
498    /// Sets the components of the Decimal from a sign, a layer and a magnitude
499    ///
500    /// This function normalizes the inputs
501    pub fn set_from_components(&mut self, sign: i8, layer: i64, mag: Number) -> Decimal {
502        self.sign = sign;
503        self.layer = layer;
504        self.mag = mag;
505
506        self.normalize();
507        *self
508    }
509
510    /// Sets the components of the Decimal from a sign, a layer and a magnitude
511    ///
512    /// This function does not normalize the inputs
513    pub fn set_from_components_no_normalize(
514        &mut self,
515        sign: i8,
516        layer: i64,
517        mag: Number,
518    ) -> Decimal {
519        self.sign = sign;
520        self.layer = layer;
521        self.mag = mag;
522
523        *self
524    }
525
526    /// Sets the components of the Decimal from a mantissa and an exponent
527    ///
528    /// This function normalizes the inputs
529    pub fn set_from_mantissa_exponent(&mut self, m: Number, e: Number) -> Decimal {
530        self.layer = 1;
531        self.sign = sign(m);
532        let mant = m.abs();
533        self.mag = e + mant.log10();
534
535        self.normalize();
536        *self
537    }
538
539    /// Sets the components of the Decimal from a mantissa and an exponent
540    ///
541    /// This function does not normalize the inputs
542    pub fn set_from_mantissa_exponent_no_normalize(&mut self, m: Number, e: Number) -> Decimal {
543        self.set_from_mantissa_exponent(m, e);
544        *self
545    }
546
547    /// Sets the components of the Decimal from a number (f64)
548    pub fn set_from_number(&mut self, n: Number) -> Decimal {
549        self.sign = sign(n);
550        self.layer = 0;
551        self.mag = n.abs();
552
553        self.normalize();
554        *self
555    }
556
557    /// Returns the Decimal as a number (f64)
558    pub fn to_number(&self) -> Number {
559        if self.layer == 0 {
560            return self.sign as f64 * self.mag;
561        }
562
563        if self.layer == 1 {
564            return self.sign as f64 * 10.0_f64.powf(self.mag);
565        }
566
567        if self.mag > 0.0 {
568            if self.sign > 0 {
569                f64::INFINITY
570            } else {
571                f64::NEG_INFINITY
572            }
573        } else {
574            0.0
575        }
576    }
577
578    /// Returns the mantissa with the specified amount of decimal places
579    pub fn mantissa_with_decimal_places(&self, places: i32) -> Number {
580        if self.mantissa().is_nan() {
581            return f64::NAN;
582        }
583
584        if self.mantissa() == 0.0 {
585            return 0.0;
586        }
587
588        decimal_places(self.mantissa(), places)
589    }
590
591    /// Returns the magnitude with the specified amount of decimal places
592    pub fn magnitude_with_decimal_places(&self, places: i32) -> Number {
593        if self.mag.is_nan() {
594            return f64::NAN;
595        }
596
597        if self.mag == 0.0 {
598            return 0.0;
599        }
600
601        decimal_places(self.mag, places)
602    }
603
604    /// Returns the Decimal as a String with the specified amount of decimal places
605    pub fn to_fixed(&self, places: usize) -> String {
606        if self.layer == 0 {
607            return format!("{:.*}", places, self.mag);
608        }
609
610        self.to_string_with_decimal_places(places, None)
611    }
612
613    /// Returns the Decimal as a String with the specified amount of precision.
614    ///
615    /// If the amount of decimal places is larger than that the exponent, this will return a fixed representation of the number.
616    ///
617    /// Otherwise, this will return a scientific representation of the number.
618    pub fn to_precision(&self, places: usize) -> String {
619        if self.exponent() <= -7.0 {
620            return format!("{:.*e}", places - 1, self);
621        }
622
623        if places as f64 > self.exponent() {
624            return self.to_fixed(places - self.exponent() as usize - 1);
625        }
626
627        format!("{:.*e}", places - 1, self)
628    }
629
630    /// Returns the Decimal as a String with the specified amount of precision.
631    ///
632    /// This follows more rules than to_precision.
633    ///
634    /// If the layer of the Decimal is 0 and the magnitude is less than 1e21 and larger than 1e-7 (or when the magnitude is 0),
635    /// this will return a fixed representation of the number.
636    /// If the layer is 0, a scientific representation of the number will be returned.
637    ///
638    /// If the layer is 1, a scientific representation of the number will be returned.
639    ///
640    /// Otherwise, a scientific representation with multiple es will be returned.
641    pub fn to_string_with_decimal_places(&self, places: usize, e_lower: Option<bool>) -> String {
642        let e = if e_lower.unwrap_or(true) { "e" } else { "E" };
643
644        if self.layer == 0 {
645            if (self.mag < 1e21 && self.mag > 1e-7) || self.mag == 0.0 {
646                return format!("{:.*}", places, self.sign as f64 * self.mag);
647            }
648            return format!(
649                "{:.*}{}{:.*}",
650                places,
651                decimal_places(self.mantissa(), places as i32),
652                e,
653                places,
654                decimal_places(self.exponent(), places as i32)
655            );
656        }
657
658        if self.layer == 1 {
659            return format!(
660                "{:.*}{}{:.*}",
661                places,
662                decimal_places(self.mantissa(), places as i32),
663                e,
664                places,
665                decimal_places(self.exponent(), places as i32)
666            );
667        }
668
669        if self.layer <= MAX_ES_IN_A_ROW as i64 {
670            format!(
671                "{}{}{:.*}",
672                if self.sign > 0 { "" } else { "-" },
673                e.repeat(self.layer as usize),
674                places,
675                decimal_places(self.mag, places as i32)
676            )
677        } else {
678            format!(
679                "{}({}^{}){:.*}",
680                if self.sign > 0 { "" } else { "-" },
681                e,
682                self.layer,
683                places,
684                decimal_places(self.mag, places as i32)
685            )
686        }
687    }
688
689    /// Returns the absolute value of the Decimal
690    pub fn abs(&self) -> Decimal {
691        Decimal::from_components_no_normalize(
692            if self.sign == 0 { 0 } else { 1 },
693            self.layer,
694            self.mag,
695        )
696    }
697
698    /// Returns a zero Decimal
699    pub fn zero() -> Decimal {
700        Decimal::from_components_no_normalize(0, 0, 0.0)
701    }
702
703    /// Returns a one Decimal
704    pub fn one() -> Decimal {
705        Decimal::from_components_no_normalize(1, 0, 1.0)
706    }
707
708    /// Returns a negative one Decimal
709    pub fn neg_one() -> Decimal {
710        Decimal::from_components_no_normalize(-1, 0, 1.0)
711    }
712
713    /// Returns a two Decimal
714    pub fn two() -> Decimal {
715        Decimal::from_components_no_normalize(1, 0, 2.0)
716    }
717
718    /// Returns a ten Decimal
719    pub fn ten() -> Decimal {
720        Decimal::from_components_no_normalize(1, 0, 10.0)
721    }
722
723    /// Returns a NaN Decimal
724    pub fn nan() -> Decimal {
725        Decimal::from_components_no_normalize(0, 0, f64::NAN)
726    }
727
728    /// Returns a positive infinity Decimal
729    pub fn inf() -> Decimal {
730        Decimal::from_components_no_normalize(1, 0, f64::INFINITY)
731    }
732
733    /// Returns a negative infinity Decimal
734    pub fn neg_inf() -> Decimal {
735        Decimal::from_components_no_normalize(-1, 0, f64::NEG_INFINITY)
736    }
737
738    /// Returns the largest safe Decimal that can be represented from an f64
739    pub fn maximum() -> Decimal {
740        Decimal::from_components_no_normalize(1, 0, f64::MAX)
741    }
742
743    /// Returns the smallest safe Decimal that can be represented from an f64
744    pub fn minimum() -> Decimal {
745        Decimal::from_components_no_normalize(1, 0, f64::MIN)
746    }
747
748    /// Rounds the Decimal to the nearest integer
749    pub fn round(&self) -> Decimal {
750        if self.mag < 0.0 {
751            return Decimal::zero();
752        }
753
754        if self.layer == 0 {
755            return Decimal::from_components(self.sign, 0, self.mag.round());
756        }
757
758        *self
759    }
760
761    /// Returns the largest Decimal less than or equal to the Decimal.
762    pub fn floor(&self) -> Decimal {
763        if self.mag < 0.0 {
764            return Decimal::zero();
765        }
766
767        if self.layer == 0 {
768            return Decimal::from_components(self.sign, 0, self.mag.floor());
769        }
770
771        *self
772    }
773
774    /// Returns the smallest Decimal greater than or equal to the Decimal.
775    pub fn ceil(&self) -> Decimal {
776        if self.mag < 0.0 {
777            return Decimal::zero();
778        }
779
780        if self.layer == 0 {
781            return Decimal::from_components(self.sign, 0, self.mag.ceil());
782        }
783
784        *self
785    }
786
787    /// Returns the integer part of the Decimal
788    pub fn trunc(&self) -> Decimal {
789        if self.mag < 0.0 {
790            return Decimal::zero();
791        }
792
793        if self.layer == 0 {
794            return Decimal::from_components(self.sign, 0, self.mag.trunc());
795        }
796
797        *self
798    }
799
800    /// Compares the absolute value of the Decimal to the absolute value of the other Decimal
801    pub fn cmpabs(&self, rhs: &Decimal) -> i8 {
802        let layer_a = if self.mag > 0.0 {
803            self.layer
804        } else {
805            -self.layer
806        };
807        let layer_b = if rhs.mag > 0.0 { rhs.layer } else { -rhs.layer };
808
809        if layer_a > layer_b {
810            return 1;
811        }
812
813        if layer_a < layer_b {
814            return -1;
815        }
816
817        if self.mag > rhs.mag {
818            return 1;
819        }
820
821        if self.mag < rhs.mag {
822            return -1;
823        }
824
825        0
826    }
827
828    /// Compares the absolute value of the Decimal to the absolute value of the other Decimal
829    /// and returns the bigger one
830    pub fn maxabs(&self, rhs: Decimal) -> Decimal {
831        if self.cmpabs(&rhs) > 0 {
832            *self
833        } else {
834            rhs
835        }
836    }
837
838    /// Compares the absolute value of the Decimal to the absolute value of the other Decimal
839    /// and returns the smaller one
840    pub fn minabs(&self, rhs: Decimal) -> Decimal {
841        if self.cmpabs(&rhs) > 0 {
842            rhs
843        } else {
844            *self
845        }
846    }
847
848    /// Returns the reciprocal of the Decimal
849    pub fn recip(&self) -> Decimal {
850        if self.mag == 0.0 {
851            return Decimal::nan();
852        }
853
854        if self.layer == 0 {
855            return Decimal::from_components(self.sign, 0, 1.0 / self.mag);
856        }
857
858        Decimal::from_components(self.sign, self.layer, -self.mag)
859    }
860
861    /// Returns the bigger of the two Decimals
862    pub fn max(&self, other: Decimal) -> Decimal {
863        if self > &other {
864            *self
865        } else {
866            other
867        }
868    }
869
870    /// Returns the smaller of the two Decimals
871    pub fn min(&self, other: Decimal) -> Decimal {
872        if self < &other {
873            *self
874        } else {
875            other
876        }
877    }
878
879    /// Clamps the Decimal to the given range
880    pub fn clamp(&self, min: Decimal, max: Decimal) -> Decimal {
881        self.max(min).min(max)
882    }
883
884    /// Clamps the Decimal to a minimum value
885    pub fn clamp_min(&self, min: Decimal) -> Decimal {
886        self.max(min)
887    }
888
889    /// Clamps the Decimal to a maximum value
890    pub fn clamp_max(&self, max: Decimal) -> Decimal {
891        self.min(max)
892    }
893
894    /// Tolerance is a relative tolerance, multiplied by the greater of the magnitudes of the two arguments.
895    /// For example, if you put in 1e-9, then any number closer to the
896    /// larger number than (larger number)*1e-9 will count as equal.
897    ///
898    /// Default tolerance is 1e-7
899    pub fn eq_tolerance(&self, other: &Decimal, tolerance: f64) -> bool {
900        if self.sign != other.sign {
901            return false;
902        }
903
904        if (self.layer - other.layer).abs() > 1 {
905            return false;
906        }
907
908        let mut mag_a = self.mag;
909        let mut mag_b = other.mag;
910        if self.layer > other.layer {
911            mag_b = f_maglog10(mag_b);
912        }
913        if other.layer > self.layer {
914            mag_a = f_maglog10(mag_a);
915        }
916
917        (mag_a - mag_b).abs() <= tolerance * mag_a.abs().max(mag_b.abs())
918    }
919
920    /// Returns the absolute log10 of the Decimal
921    pub fn abs_log10(&self) -> Decimal {
922        if self.sign == 0 {
923            return Decimal::nan();
924        }
925
926        if self.layer > 0 {
927            return Decimal::from_components(sign(self.mag), self.layer - 1, self.mag.abs());
928        }
929
930        Decimal::from_components(1, 0, self.mag.log10())
931    }
932
933    /// Returns log10 of the Decimal
934    pub fn log10(&self) -> Decimal {
935        if self.sign <= 0 {
936            return Decimal::nan();
937        }
938
939        if self.layer > 0 {
940            return Decimal::from_components(sign(self.mag), self.layer - 1, self.mag.abs());
941        }
942
943        Decimal::from_components(self.sign, 0, self.mag.log10())
944    }
945
946    /// Returns the log of the Decimal with the given base
947    pub fn log(&self, base: Decimal) -> Decimal {
948        if self.sign <= 0 {
949            return Decimal::nan();
950        }
951
952        if base.sign <= 0 {
953            return Decimal::nan();
954        }
955
956        if base.sign == 1 && base.layer == 0 && (base.mag - 1.0).abs() < 1e-10 {
957            return Decimal::nan();
958        }
959
960        if self.layer == 0 && base.layer == 0 {
961            return Decimal::from_components(self.sign, 0, self.mag.ln() / base.mag.ln());
962        }
963
964        self.log10() / base.log10()
965    }
966
967    /// Returns the log2 of the Decimal
968    pub fn log2(&self) -> Decimal {
969        if self.sign <= 0 {
970            return Decimal::nan();
971        }
972
973        if self.layer == 0 {
974            return Decimal::from_components(self.sign, 0, self.mag.log2());
975        }
976
977        if self.layer == 1 {
978            return Decimal::from_components(
979                sign(self.mag),
980                0,
981                self.mag.abs() * std::f64::consts::LOG2_10,
982            );
983        }
984
985        if self.layer == 2 {
986            return Decimal::from_components(
987                sign(self.mag),
988                1,
989                self.mag.abs() + 0.5213902276543247,
990            );
991        }
992
993        Decimal::from_components(sign(self.mag), self.layer - 1, self.mag.abs())
994    }
995
996    /// Returns the natural log of the Decimal
997    pub fn ln(&self) -> Decimal {
998        if self.sign <= 0 {
999            return Decimal::nan();
1000        }
1001
1002        if self.layer == 0 {
1003            return Decimal::from_components(self.sign, 0, self.mag.ln());
1004        }
1005
1006        if self.layer == 1 {
1007            return Decimal::from_components(
1008                sign(self.mag),
1009                0,
1010                self.mag.abs() * std::f64::consts::LN_10,
1011            );
1012        }
1013
1014        if self.layer == 2 {
1015            return Decimal::from_components(
1016                sign(self.mag),
1017                1,
1018                self.mag.abs() + 0.36221568869946325,
1019            );
1020        }
1021
1022        Decimal::from_components(sign(self.mag), self.layer - 1, self.mag.abs())
1023    }
1024
1025    /// Returns the Decimal to the power of the given exponent
1026    pub fn pow(self, exp: Decimal) -> Decimal {
1027        let a = self;
1028        let b = exp;
1029
1030        if a.sign == 0 {
1031            return if b == Decimal::from_number(0.0) {
1032                Decimal::one()
1033            } else {
1034                a
1035            };
1036        }
1037
1038        if a.sign == 1 && a.layer == 0 && (a.mag - 1.0).abs() < 1e-10 {
1039            return a;
1040        }
1041
1042        if b.sign == 0 {
1043            return Decimal::one();
1044        }
1045
1046        if b.sign == 1 && b.layer == 0 && (b.mag - 1.0).abs() < 1e-10 {
1047            return a;
1048        }
1049
1050        let result = (a.abs_log10() * b).pow10();
1051
1052        if self.sign == -1 && ((b.to_number() % 2.0).abs() - 1.0).abs() < 1e-10 {
1053            return -result;
1054        }
1055
1056        result
1057    }
1058
1059    /// Returns the Decimal raised to the next power of 10
1060    pub fn pow10(self) -> Decimal {
1061        if !self.mag.is_finite() {
1062            return Decimal::nan();
1063        }
1064
1065        let mut a = self;
1066
1067        if a.layer == 0 {
1068            let new_mag = 10.0_f64.powf(a.sign as f64 * a.mag);
1069            if new_mag.is_finite() && new_mag.abs() > 0.1 {
1070                return Decimal::from_components(1, 0, new_mag);
1071            } else {
1072                if a.sign == 0 {
1073                    return Decimal::one();
1074                }
1075                a = Decimal::from_components_no_normalize(a.sign, a.layer + 1, a.mag.log10());
1076            }
1077        }
1078
1079        if a.sign > 0 && a.mag > 0.0 {
1080            return Decimal::from_components(a.sign, a.layer + 1, a.mag);
1081        }
1082
1083        if a.sign < 0 && a.mag > 0.0 {
1084            return Decimal::from_components(-a.sign, a.layer + 1, -a.mag);
1085        }
1086
1087        Decimal::one()
1088    }
1089
1090    /// Returns the n-th root of the Decimal
1091    pub fn root(self, n: Decimal) -> Decimal {
1092        self.pow(n.recip())
1093    }
1094
1095    /// Returns the exponential function of the Decimal
1096    pub fn exp(self) -> Decimal {
1097        if self.mag < 0.0 {
1098            return Decimal::one();
1099        }
1100
1101        if self.layer == 0 && self.mag <= 709.7 {
1102            return Decimal::from_number((self.sign as f64 * self.mag).exp());
1103        }
1104
1105        if self.layer == 0 {
1106            return Decimal::from_components(
1107                1,
1108                1,
1109                self.sign as f64 * std::f64::consts::E.log10() * self.mag,
1110            );
1111        }
1112
1113        if self.layer == 1 {
1114            return Decimal::from_components(
1115                1,
1116                2,
1117                self.sign as f64 * std::f64::consts::LOG10_E.log10() + self.mag,
1118            );
1119        }
1120
1121        Decimal::from_components(1, self.layer + 1, self.sign as f64 * self.mag)
1122    }
1123
1124    /// Returns the gamma function of the Decimal
1125    pub fn gamma(&self) -> Decimal {
1126        if self.mag < 0.0 {
1127            return self.recip();
1128        }
1129
1130        if self.layer == 0 {
1131            if self < &Decimal::from_components_no_normalize(1, 0, 24.0) {
1132                return Decimal::from_number(f_gamma(self.sign as f64 * self.mag));
1133            }
1134
1135            let t = self.mag - 1.0;
1136            let mut l = 0.9189385332046727;
1137            l += (t + 0.5) * t.ln();
1138            l -= t;
1139            let n2 = t * t;
1140            let mut np = t;
1141            let mut lm = 12.0 * np;
1142            let adj = 1.0 / lm;
1143            let l2 = l + adj;
1144            if (l2 - l).abs() < 1e-10 {
1145                return Decimal::from_number(l).exp();
1146            }
1147
1148            l = l2;
1149            np *= n2;
1150            lm = 1260.0 * np;
1151            let mut lt = 1.0 / lm;
1152            l += lt;
1153            np *= n2;
1154            lm = 1680.0 * np;
1155            lt = 1.0 / lm;
1156            l -= lt;
1157            return Decimal::from_number(l).exp();
1158        }
1159
1160        if self.layer == 1 {
1161            return (*self * (self.ln() - Decimal::from_number(1.0))).exp();
1162        }
1163
1164        self.exp()
1165    }
1166
1167    /// Returns the factorial of the Decimal
1168    pub fn factorial(&self) -> Decimal {
1169        if self.mag < 0.0 {
1170            return (*self + Decimal::from_number(1.0)).gamma();
1171        }
1172
1173        if self.layer == 0 {
1174            return (*self + Decimal::from_number(1.0)).gamma();
1175        }
1176
1177        if self.layer == 1 {
1178            return (*self * self.ln() - Decimal::from_number(1.0)).exp();
1179        }
1180
1181        self.exp()
1182    }
1183
1184    /// Returns the natural logarithm of the gamma function of the Decimal
1185    pub fn ln_gamma(&self) -> Decimal {
1186        self.gamma().ln()
1187    }
1188
1189    /// Returns the Decimal squared
1190    pub fn sqr(&self) -> Decimal {
1191        self.pow(Decimal::from_number(2.0))
1192    }
1193
1194    /// Returns the square root of the Decimal
1195    pub fn sqrt(&self) -> Decimal {
1196        if self.layer == 0 {
1197            return Decimal::from_number((self.sign as f64 * self.mag).sqrt());
1198        }
1199
1200        if self.layer == 1 {
1201            return Decimal::from_components(1, 2, self.mag.log10() - std::f64::consts::LOG10_2);
1202        }
1203
1204        let mut result = Decimal::from_components_no_normalize(self.sign, self.layer - 1, self.mag)
1205            / Decimal::from_components_no_normalize(1, 0, 2.0);
1206        result.layer += 1;
1207        result.normalize();
1208
1209        result
1210    }
1211
1212    /// Returns the Decimal cubed
1213    pub fn cube(&self) -> Decimal {
1214        self.pow(Decimal::from_number(3.0))
1215    }
1216
1217    /// Returns the cube root of the Decimal
1218    pub fn cbrt(&self) -> Decimal {
1219        self.pow(Decimal::from_number(1.0) / Decimal::from_number(3.0))
1220    }
1221
1222    /// Tetrates the Decimal to the given height.
1223    ///
1224    /// Source: <https://andydude.github.io/tetration/archives/tetration2/ident.html>
1225    pub fn tetrate(&self, height: Option<Number>, payload: Option<Decimal>) -> Decimal {
1226        let mut height = height.unwrap_or(2.0_f64);
1227        let mut payload =
1228            payload.unwrap_or_else(|| Decimal::from_components_no_normalize(1, 0, 1.0));
1229
1230        if height.is_infinite() && height.is_sign_positive() {
1231            let neg_ln = self.ln().neg();
1232            return neg_ln.lambertw().expect("Expected number higher than -1") / neg_ln;
1233        }
1234
1235        if height < 0.0 {
1236            return payload.iteratedlog(*self, -height);
1237        }
1238
1239        let old_height = height;
1240        height = height.trunc();
1241        let fract_height = old_height - height;
1242
1243        if fract_height != 0.0 {
1244            if payload == Decimal::one() {
1245                height += 1.0;
1246                payload = Decimal::from_number(fract_height);
1247            } else if *self == Decimal::from_number(10.0) {
1248                payload = payload.layer_add_10(Decimal::from_number(fract_height));
1249            } else {
1250                payload = payload.layer_add(fract_height, *self);
1251            }
1252        }
1253
1254        for i in 0..height as i64 {
1255            payload = self.pow(payload);
1256            // bail if we're NaN
1257            if !payload.mag.is_finite() {
1258                return payload;
1259            }
1260
1261            if payload.layer - self.layer > 3 {
1262                return Decimal::from_components_no_normalize(
1263                    payload.sign,
1264                    payload.layer + (height as i64 - i - 1),
1265                    payload.mag,
1266                );
1267            }
1268
1269            if i > 100 {
1270                return payload;
1271            }
1272        }
1273
1274        payload
1275    }
1276
1277    /// Returns the Decimal, iteratively exponentiated
1278    ///
1279    /// Equates to tetrating to the same height.
1280    pub fn iteratedexp(&self, height: Option<Number>, payload: Option<Decimal>) -> Decimal {
1281        self.tetrate(height, payload)
1282    }
1283
1284    /// Iterated log: The result of applying log(base) 'times' times in a row.
1285    /// Approximately equal to subtratcting (times) from the number's slo representation.
1286    /// Equates to tetrating to a negative height.
1287    pub fn iteratedlog(&self, base: Decimal, mut times: f64) -> Decimal {
1288        if times < 0.0 {
1289            return base.tetrate(Some(-times), Some(*self));
1290        }
1291
1292        let mut result = *self;
1293        let full_times = times;
1294        times = times.trunc();
1295        let fraction = full_times - times;
1296
1297        if result.layer - base.layer > 3 {
1298            let layer_loss = times.min((result.layer - base.layer - 3) as f64);
1299            times -= layer_loss;
1300            result.layer -= layer_loss as i64;
1301        }
1302
1303        for i in 0..times as i64 {
1304            result = result.log(base);
1305            if !result.mag.is_finite() {
1306                return result;
1307            }
1308            if i > 100 {
1309                return result;
1310            }
1311        }
1312
1313        if fraction > 0.0 && fraction < 1.0 {
1314            if base == Decimal::from_number(10.0) {
1315                result = result.layer_add_10(Decimal::from_number(-fraction));
1316            } else {
1317                result = result.layer_add(-fraction, base);
1318            }
1319        }
1320
1321        result
1322    }
1323
1324    /// Returns the super-logarithm of the Decimal
1325    pub fn slog(&self, base_opt: Option<Decimal>) -> Decimal {
1326        if self.mag < 0.0 {
1327            return Decimal::neg_one();
1328        }
1329
1330        let mut result: f64 = 0.0;
1331        let base = base_opt.unwrap_or_else(|| Decimal::from_number(10.0));
1332        let mut copy = *self;
1333
1334        if copy.layer - base.layer > 3 {
1335            let layer_loss = copy.layer - base.layer - 3;
1336            result += layer_loss as f64;
1337            copy.layer -= layer_loss;
1338        }
1339
1340        for _ in 0..100 {
1341            if copy < Decimal::zero() {
1342                copy = base.pow(copy);
1343                result -= 1.0;
1344            }
1345
1346            if copy <= Decimal::one() {
1347                return Decimal::from_number(result + copy.to_number() - 1.0);
1348            }
1349
1350            result += 1.0;
1351            copy = copy.log(base);
1352        }
1353
1354        Decimal::from_number(result)
1355    }
1356
1357    /// Adds or removes layers from a Decimal using linear approximation
1358    pub fn layer_add_10(&self, diff: Decimal) -> Decimal {
1359        let mut diff = diff.to_number();
1360        let mut result = *self;
1361
1362        if diff >= 1.0 {
1363            let layer_add = diff.trunc();
1364            diff -= layer_add;
1365            result.layer += layer_add as i64;
1366        }
1367
1368        if diff <= -1.0 {
1369            let layer_add = diff.trunc();
1370            diff -= layer_add;
1371            result.layer += layer_add as i64;
1372            if result.layer < 0 {
1373                for _ in 0..100 {
1374                    result.layer += 1;
1375                    result.mag = result.mag.log10();
1376                    if !result.mag.is_finite() {
1377                        return result;
1378                    }
1379
1380                    if result.layer >= 0 {
1381                        break;
1382                    }
1383                }
1384            }
1385        }
1386
1387        if diff > 0.0 {
1388            let mut subtract_layers_later: i64 = 0;
1389            while result.mag.is_finite() && result.mag < 10.0 {
1390                result.mag = 10.0_f64.powf(result.mag);
1391                subtract_layers_later += 1;
1392            }
1393
1394            if result.mag > 1e10_f64 {
1395                result.mag = result.mag.log10();
1396                result.layer += 1;
1397            }
1398
1399            let diff_to_next_slog = (1e10_f64.ln() / result.mag.ln()).log10();
1400            if diff_to_next_slog < diff {
1401                result.mag = 1e10_f64.log10();
1402                result.layer += 1;
1403                diff -= diff_to_next_slog;
1404            }
1405
1406            result.mag = result.mag.powf(10.0_f64.powf(diff));
1407
1408            while subtract_layers_later > 0 {
1409                result.mag = result.mag.log10();
1410                subtract_layers_later -= 1;
1411            }
1412        }
1413
1414        if diff < 0.0 {
1415            let mut subtract_layers_later: i64 = 0;
1416
1417            while result.mag.is_finite() && result.mag < 10.0 {
1418                result.mag = 10.0_f64.powf(result.mag);
1419                subtract_layers_later += 1;
1420            }
1421
1422            if result.mag > 1e10_f64 {
1423                result.mag = result.mag.log10();
1424                result.layer += 1;
1425            }
1426
1427            let diff_to_next_slog = (1.0 / result.mag.log10()).log10();
1428            if diff_to_next_slog > diff {
1429                result.mag = 1e10_f64;
1430                result.layer -= 1;
1431                diff -= diff_to_next_slog;
1432            }
1433
1434            result.mag = result.mag.powf(10.0_f64.powf(diff));
1435
1436            while subtract_layers_later > 0 {
1437                result.mag = result.mag.log10();
1438                subtract_layers_later -= 1;
1439            }
1440        }
1441
1442        while result.layer < 0 {
1443            result.layer += 1;
1444            result.mag = result.mag.log10();
1445        }
1446
1447        result.normalize();
1448        result
1449    }
1450
1451    /// Adds `diff` to the Decimal's slog(base) representation
1452    pub fn layer_add(&self, diff: f64, base: Decimal) -> Decimal {
1453        let slog_this = self.slog(Some(base)).to_number();
1454        let slog_dest = slog_this + diff;
1455
1456        if slog_dest >= 0.0 {
1457            return base.tetrate(Some(slog_dest), None);
1458        }
1459
1460        if !slog_dest.is_finite() {
1461            return Decimal::nan();
1462        }
1463
1464        if slog_dest >= -1.0 {
1465            return base.tetrate(Some(slog_dest + 1.0), None).log(base);
1466        }
1467
1468        base.tetrate(Some(slog_dest + 2.0), None)
1469            .log(base)
1470            .log(base)
1471    }
1472
1473    /// Returns the product logarithm of the Decimal
1474    pub fn lambertw(&self) -> Result<Decimal, BreakEternityError> {
1475        if self < &Decimal::from_number(-0.3678794411710499) {
1476            return Err(BreakEternityError::LambertWError);
1477        }
1478
1479        if self.mag < 0.0 {
1480            return Ok(Decimal::from_number(f_lambertw(self.to_number(), None)?));
1481        }
1482
1483        if self.layer == 0 {
1484            return Ok(Decimal::from_number(f_lambertw(
1485                self.sign as f64 * self.mag,
1486                None,
1487            )?));
1488        }
1489
1490        if self.layer == 1 || self.layer == 2 {
1491            return d_lambertw(*self, None);
1492        }
1493
1494        Ok(Decimal::from_components_no_normalize(
1495            self.sign,
1496            self.layer - 1,
1497            self.mag,
1498        ))
1499    }
1500
1501    /// Returns the super square root of the Decimal
1502    ///
1503    /// Essentially "what number, tetrated to height 2, equals this?"
1504    pub fn ssqrt(&self) -> Decimal {
1505        if self.sign == 1 && self.layer >= 3 {
1506            return Decimal::from_components_no_normalize(self.sign, self.layer - 1, self.mag);
1507        }
1508
1509        let ln_x = self.ln();
1510        ln_x / ln_x.lambertw().expect("Expected number higher than -1")
1511    }
1512
1513    /// The result of tetrating the Decimal `height` times in a row.
1514    pub fn pentate(&self, height: Option<Number>, payload: Option<Decimal>) -> Decimal {
1515        let mut height = height.unwrap_or(2.0_f64);
1516        let mut payload =
1517            payload.unwrap_or_else(|| Decimal::from_components_no_normalize(1, 0, 1.0));
1518
1519        let old_height = height;
1520        height = height.trunc();
1521        let fract_height = old_height - height;
1522
1523        if fract_height != 0.0 {
1524            if payload == Decimal::one() {
1525                height += 1.0;
1526                payload = Decimal::from_number(fract_height);
1527            } else if *self == Decimal::from_number(10.0) {
1528                payload = payload.layer_add_10(Decimal::from_number(fract_height));
1529            } else {
1530                payload = payload.layer_add(fract_height, *self);
1531            }
1532        }
1533
1534        for i in 0..height as i64 {
1535            payload = self.tetrate(Some(payload.to_number()), None);
1536            if !payload.mag.is_finite() {
1537                return payload;
1538            }
1539            if i > 10 {
1540                return payload;
1541            }
1542        }
1543
1544        payload
1545    }
1546
1547    /// Returns the sin of the Decimal
1548    pub fn sin(&self) -> Decimal {
1549        if self.mag < 0.0 {
1550            return *self;
1551        }
1552
1553        if self.layer == 0 {
1554            return Decimal::from_number((self.sign as f64 * self.mag).sin());
1555        }
1556
1557        Decimal::from_components_no_normalize(0, 0, 0.0)
1558    }
1559
1560    /// Returns the cos of the Decimal
1561    pub fn cos(&self) -> Decimal {
1562        if self.mag < 0.0 {
1563            return Decimal::one();
1564        }
1565
1566        if self.layer == 0 {
1567            return Decimal::from_number((self.sign as f64 * self.mag).cos());
1568        }
1569
1570        Decimal::from_components_no_normalize(0, 0, 0.0)
1571    }
1572
1573    /// Returns the tan of the Decimal
1574    pub fn tan(&self) -> Decimal {
1575        if self.mag < 0.0 {
1576            return Decimal::from_number((self.sign as f64 * self.mag).tan());
1577        }
1578
1579        if self.layer == 0 {
1580            return Decimal::from_number((self.sign as f64 * self.mag).tan());
1581        }
1582
1583        Decimal::from_components_no_normalize(0, 0, 0.0)
1584    }
1585
1586    /// Returns the asin of the Decimal
1587    pub fn asin(&self) -> Decimal {
1588        if self.mag < 0.0 {
1589            return *self;
1590        }
1591
1592        if self.layer == 0 {
1593            return Decimal::from_number((self.sign as f64 * self.mag).asin());
1594        }
1595
1596        Decimal::nan()
1597    }
1598
1599    /// Returns the acos of the Decimal
1600    pub fn acos(&self) -> Decimal {
1601        if self.mag < 0.0 {
1602            return Decimal::from_number(self.to_number().acos());
1603        }
1604
1605        if self.layer == 0 {
1606            return Decimal::from_number((self.sign as f64 * self.mag).acos());
1607        }
1608
1609        Decimal::nan()
1610    }
1611
1612    /// Returns the atan of the Decimal
1613    pub fn atan(&self) -> Decimal {
1614        if self.mag < 0.0 {
1615            return *self;
1616        }
1617
1618        if self.layer == 0 {
1619            return Decimal::from_number((self.sign as f64 * self.mag).atan());
1620        }
1621
1622        Decimal::from_number(std::f64::INFINITY.atan())
1623    }
1624
1625    /// Returns the sinh of the Decimal
1626    pub fn sinh(&self) -> Decimal {
1627        (self.exp() - (-*self).exp()) / Decimal::from_number(2.0)
1628    }
1629
1630    /// Returns the cosh of the Decimal
1631    pub fn cosh(&self) -> Decimal {
1632        (self.exp() + (-*self).exp()) / Decimal::from_number(2.0)
1633    }
1634
1635    /// Returns the tanh of the Decimal
1636    pub fn tanh(&self) -> Decimal {
1637        self.sinh() / self.cosh()
1638    }
1639
1640    /// Returns the asinh of the Decimal
1641    pub fn asinh(&self) -> Decimal {
1642        (*self + (self.sqr() + Decimal::from_number(1.0)).sqrt()).ln()
1643    }
1644
1645    /// Returns the acosh of the Decimal
1646    pub fn acosh(&self) -> Decimal {
1647        (*self + (self.sqr() - Decimal::from_number(1.0)).sqrt()).ln()
1648    }
1649
1650    /// Returns the atanh of the Decimal
1651    pub fn atanh(&self) -> Decimal {
1652        if self.abs() >= Decimal::from_number(1.0) {
1653            return Decimal::nan();
1654        }
1655
1656        (*self + Decimal::from_number(1.0))
1657            / (Decimal::from_number(1.0) - *self).ln()
1658            / Decimal::from_number(2.0)
1659    }
1660}
1661
1662impl PartialEq for Decimal {
1663    fn eq(&self, other: &Self) -> bool {
1664        // Special edge cases for NaN and infinities
1665        if self.mag.is_nan() && other.mag.is_nan() {
1666            return true;
1667        }
1668
1669        if (self.mag.is_infinite() && self.mag.is_sign_positive())
1670            && (other.mag.is_infinite() && other.mag.is_sign_positive())
1671        {
1672            return true;
1673        }
1674
1675        if (self.mag.is_infinite() && self.mag.is_sign_negative())
1676            && (other.mag.is_infinite() && other.mag.is_sign_negative())
1677        {
1678            return true;
1679        }
1680
1681        self.sign == other.sign && self.layer == other.layer && (self.mag - other.mag).abs() < 1e-10
1682    }
1683}
1684
1685impl Eq for Decimal {}
1686
1687impl PartialOrd for Decimal {
1688    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
1689        Some(self.cmp(other))
1690    }
1691}
1692
1693impl Ord for Decimal {
1694    #[allow(clippy::comparison_chain)]
1695    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
1696        if self.sign > other.sign {
1697            return std::cmp::Ordering::Greater;
1698        }
1699
1700        if self.sign < other.sign {
1701            return std::cmp::Ordering::Less;
1702        }
1703
1704        let cmp_abs = self.cmpabs(other) * self.sign;
1705        if cmp_abs > 0 {
1706            std::cmp::Ordering::Greater
1707        } else if cmp_abs < 0 {
1708            std::cmp::Ordering::Less
1709        } else {
1710            std::cmp::Ordering::Equal
1711        }
1712    }
1713}
1714
1715impl std::hash::Hash for Decimal {
1716    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
1717        self.sign.hash(state);
1718        self.layer.hash(state);
1719        self.mag.to_bits().hash(state);
1720    }
1721}
1722
1723impl Add<Decimal> for Decimal {
1724    type Output = Decimal;
1725
1726    fn add(self, rhs: Decimal) -> Self::Output {
1727        if !self.mag.is_finite() {
1728            return self;
1729        }
1730
1731        if self.sign == 0 {
1732            return rhs;
1733        }
1734        if rhs.sign == 0 {
1735            return self;
1736        }
1737
1738        if self.sign == -(rhs.sign) && self.layer == rhs.layer && (self.mag - rhs.mag).abs() < 1e-10
1739        {
1740            return Decimal::zero();
1741        }
1742
1743        let a: Decimal;
1744        let b: Decimal;
1745
1746        if self.layer >= 2 || rhs.layer >= 2 {
1747            return self.maxabs(rhs);
1748        }
1749
1750        if self.cmpabs(&rhs) > 0 {
1751            a = self;
1752            b = rhs;
1753        } else {
1754            a = rhs;
1755            b = self;
1756        }
1757
1758        if a.layer == 0 && b.layer == 0 {
1759            return Decimal::from_number(a.sign as f64 * a.mag + b.sign as f64 * b.mag);
1760        }
1761
1762        let layer_a = a.layer * sign(a.mag) as i64;
1763        let layer_b = b.layer * sign(b.mag) as i64;
1764
1765        if layer_a - layer_b >= 2 {
1766            return a;
1767        }
1768
1769        if layer_a == 0 && layer_b == -1 {
1770            if (b.mag - a.mag.log10()).abs() > MAX_FLOAT_PRECISION as f64 {
1771                return a;
1772            } else {
1773                let mag_diff = 10.0_f64.powf(a.mag.log10() - b.mag);
1774                let mantissa = b.sign as f64 + (a.sign as f64 * mag_diff);
1775                return Decimal::from_components(sign(mantissa), 1, b.mag + mantissa.abs().log10());
1776            }
1777        }
1778
1779        if layer_a == 1 && layer_b == 0 {
1780            if (a.mag - b.mag.log10()).abs() > MAX_FLOAT_PRECISION as f64 {
1781                return a;
1782            } else {
1783                let mag_diff = 10.0_f64.powf(a.mag - b.mag.log10());
1784                let mantissa = b.sign as f64 + (a.sign as f64 * mag_diff);
1785                return Decimal::from_components(
1786                    sign(mantissa),
1787                    1,
1788                    b.mag.log10() + mantissa.abs().log10(),
1789                );
1790            }
1791        }
1792
1793        if (a.mag - b.mag).abs() > MAX_FLOAT_PRECISION as f64 {
1794            return a;
1795        }
1796
1797        let mag_diff = 10.0_f64.powf(a.mag - b.mag);
1798        let mantissa = b.sign as f64 + (a.sign as f64 * mag_diff);
1799        let new_mag = b.mag + mantissa.abs().log10();
1800        Decimal::from_components(sign(mantissa), 1, new_mag)
1801    }
1802}
1803
1804impl Sub<Decimal> for Decimal {
1805    type Output = Decimal;
1806
1807    fn sub(self, rhs: Decimal) -> Self::Output {
1808        self + -rhs
1809    }
1810}
1811
1812impl Mul<Decimal> for Decimal {
1813    type Output = Decimal;
1814
1815    fn mul(self, rhs: Decimal) -> Self::Output {
1816        if self.sign == 0 || rhs.sign == 0 {
1817            return Decimal::zero();
1818        }
1819
1820        if self.layer == rhs.layer && (self.mag - -rhs.mag).abs() < 1e-10 {
1821            return Decimal::from_components_no_normalize(self.sign * rhs.sign, 0, 1.0);
1822        }
1823
1824        let a: Decimal;
1825        let b: Decimal;
1826
1827        if (self.layer > rhs.layer) || (self.layer == rhs.layer && self.mag.abs() > rhs.mag.abs()) {
1828            a = self;
1829            b = rhs;
1830        } else {
1831            a = rhs;
1832            b = self;
1833        }
1834
1835        if a.layer == 0 && b.layer == 0 {
1836            return Decimal::from_number(a.sign as f64 * b.sign as f64 * a.mag * b.mag);
1837        }
1838
1839        if a.layer >= 3 || (a.layer - b.layer >= 2) {
1840            return Decimal::from_components(a.sign * b.sign, a.layer, a.mag);
1841        }
1842
1843        if a.layer == 1 && b.layer == 0 {
1844            return Decimal::from_components(a.sign * b.sign, 1, a.mag + b.mag.log10());
1845        }
1846
1847        if a.layer == 1 && b.layer == 1 {
1848            return Decimal::from_components(a.sign * b.sign, 1, a.mag + b.mag);
1849        }
1850
1851        if a.layer == 2 && b.layer == 1 {
1852            let new_mag = Decimal::from_components(sign(a.mag), a.layer - 1, a.mag.abs())
1853                + Decimal::from_components(sign(b.mag), b.layer - 1, b.mag.abs());
1854            return Decimal::from_components(
1855                a.sign * b.sign,
1856                new_mag.layer + 1,
1857                new_mag.sign as f64 * new_mag.mag,
1858            );
1859        }
1860
1861        if a.layer == 2 && b.layer == 2 {
1862            let new_mag = Decimal::from_components(sign(a.mag), a.layer - 1, a.mag.abs())
1863                + Decimal::from_components(sign(b.mag), b.layer - 1, b.mag.abs());
1864            return Decimal::from_components(
1865                a.sign * b.sign,
1866                new_mag.layer + 1,
1867                new_mag.sign as f64 * new_mag.mag,
1868            );
1869        }
1870
1871        Decimal::inf()
1872    }
1873}
1874
1875impl Div<Decimal> for Decimal {
1876    type Output = Decimal;
1877
1878    /// Division of two decimals by multiplying the denominator by the reciprocal of the numerator.
1879    #[allow(clippy::suspicious_arithmetic_impl)]
1880    fn div(self, rhs: Decimal) -> Self::Output {
1881        self * rhs.recip()
1882    }
1883}
1884
1885impl AddAssign<Decimal> for Decimal {
1886    fn add_assign(&mut self, rhs: Decimal) {
1887        *self = *self + rhs;
1888    }
1889}
1890
1891impl SubAssign<Decimal> for Decimal {
1892    fn sub_assign(&mut self, rhs: Decimal) {
1893        *self = *self - rhs;
1894    }
1895}
1896
1897impl MulAssign<Decimal> for Decimal {
1898    fn mul_assign(&mut self, rhs: Decimal) {
1899        *self = *self * rhs;
1900    }
1901}
1902
1903impl DivAssign<Decimal> for Decimal {
1904    fn div_assign(&mut self, rhs: Decimal) {
1905        *self = *self / rhs;
1906    }
1907}
1908
1909impl RemAssign<Decimal> for Decimal {
1910    fn rem_assign(&mut self, rhs: Decimal) {
1911        *self = *self % rhs;
1912    }
1913}
1914
1915impl Rem<Decimal> for Decimal {
1916    type Output = Decimal;
1917
1918    fn rem(self, rhs: Decimal) -> Self::Output {
1919        if rhs == Decimal::zero() {
1920            return Decimal::zero();
1921        }
1922
1923        if self.sign * rhs.sign == -1 {
1924            return self.abs().rem(rhs.abs()).neg();
1925        }
1926
1927        if self.sign == -1 {
1928            return self.abs().rem(rhs.abs());
1929        }
1930
1931        self - (self / rhs).floor() * rhs
1932    }
1933}
1934
1935impl Neg for Decimal {
1936    type Output = Decimal;
1937
1938    fn neg(self) -> Decimal {
1939        Decimal::from_components_no_normalize(-self.sign, self.layer, self.mag)
1940    }
1941}
1942
1943#[cfg(feature = "serde")]
1944mod serde {
1945    use super::*;
1946
1947    impl serde_crate::Serialize for Decimal {
1948        fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1949        where
1950            S: serde_crate::Serializer,
1951        {
1952            serializer.serialize_str(&self.to_string())
1953        }
1954    }
1955
1956    impl<'de> serde_crate::Deserialize<'de> for Decimal {
1957        fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
1958        where
1959            D: serde_crate::Deserializer<'de>,
1960        {
1961            let d = String::deserialize(deserializer)?;
1962            let dec: Result<Decimal, BreakEternityError> = d.as_str().try_into();
1963            dec.map_err(|_| serde_crate::de::Error::custom("Could not parse Decimal"))
1964        }
1965    }
1966}
1967
1968impl LowerExp for Decimal {
1969    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1970        if *self == Decimal::inf() {
1971            return write!(f, "Infinity");
1972        }
1973
1974        if *self == Decimal::neg_inf() {
1975            return write!(f, "-Infinity");
1976        }
1977
1978        if *self == Decimal::nan() {
1979            return write!(f, "NaN");
1980        }
1981
1982        let precision = f.precision().unwrap_or(2);
1983
1984        if self.layer == 0 {
1985            return write!(f, "{:.*e}", precision, self.sign as f64 * self.mag);
1986        }
1987        write!(
1988            f,
1989            "{}",
1990            self.to_string_with_decimal_places(precision, Some(true))
1991        )
1992    }
1993}
1994
1995impl UpperExp for Decimal {
1996    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1997        if *self == Decimal::inf() {
1998            return write!(f, "Infinity");
1999        }
2000
2001        if *self == Decimal::neg_inf() {
2002            return write!(f, "-Infinity");
2003        }
2004
2005        if *self == Decimal::nan() {
2006            return write!(f, "NaN");
2007        }
2008
2009        let precision = f.precision().unwrap_or(2);
2010
2011        if self.layer == 0 {
2012            return write!(f, "{:.*E}", precision, self.sign as f64 * self.mag);
2013        }
2014        write!(
2015            f,
2016            "{}",
2017            self.to_string_with_decimal_places(precision, Some(false))
2018        )
2019    }
2020}
2021
2022impl Display for Decimal {
2023    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2024        if *self == Decimal::inf() {
2025            return write!(f, "Infinity");
2026        }
2027
2028        if *self == Decimal::neg_inf() {
2029            return write!(f, "-Infinity");
2030        }
2031
2032        if *self == Decimal::nan() {
2033            return write!(f, "NaN");
2034        }
2035
2036        if self.layer == 0 {
2037            if (self.mag < 1e21 && self.mag > 1e-7) || self.mag == 0.0 {
2038                return write!(f, "{}", self.sign as f64 * self.mag);
2039            }
2040            return write!(f, "{}e{}", self.mantissa(), self.exponent());
2041        }
2042        if self.layer == 1 {
2043            return write!(f, "{}e{}", self.mantissa(), self.exponent());
2044        }
2045        if self.layer <= MAX_ES_IN_A_ROW as i64 {
2046            return write!(
2047                f,
2048                "{}{}{}",
2049                if self.sign == -1 { "-" } else { "" },
2050                "e".repeat(self.layer as usize),
2051                self.mag
2052            );
2053        }
2054        write!(
2055            f,
2056            "{}(e^{}){}",
2057            if self.sign == -1 { "-" } else { "" },
2058            self.layer,
2059            self.mag
2060        )
2061    }
2062}
2063
2064macro_rules! impl_from_primitive {
2065    ($prim_type:ty) => {
2066        impl From<$prim_type> for Decimal {
2067            fn from(prim: $prim_type) -> Self {
2068                Decimal::from_number(prim as f64)
2069            }
2070        }
2071    };
2072}
2073
2074macro_rules! impl_ops_primitive {
2075    ($prim_type:ty) => {
2076        impl Add<$prim_type> for Decimal {
2077            type Output = Decimal;
2078
2079            fn add(self, rhs: $prim_type) -> Self::Output {
2080                self + Decimal::from_number(rhs as f64)
2081            }
2082        }
2083
2084        impl Add<Decimal> for $prim_type {
2085            type Output = Decimal;
2086
2087            fn add(self, rhs: Decimal) -> Self::Output {
2088                Decimal::from_number(self as f64) + rhs
2089            }
2090        }
2091
2092        impl Sub<$prim_type> for Decimal {
2093            type Output = Decimal;
2094
2095            fn sub(self, rhs: $prim_type) -> Self::Output {
2096                self - Decimal::from_number(rhs as f64)
2097            }
2098        }
2099
2100        impl Sub<Decimal> for $prim_type {
2101            type Output = Decimal;
2102
2103            fn sub(self, rhs: Decimal) -> Self::Output {
2104                Decimal::from_number(self as f64) - rhs
2105            }
2106        }
2107
2108        impl Mul<$prim_type> for Decimal {
2109            type Output = Decimal;
2110
2111            fn mul(self, rhs: $prim_type) -> Self::Output {
2112                self * Decimal::from_number(rhs as f64)
2113            }
2114        }
2115
2116        impl Mul<Decimal> for $prim_type {
2117            type Output = Decimal;
2118
2119            fn mul(self, rhs: Decimal) -> Self::Output {
2120                Decimal::from_number(self as f64) * rhs
2121            }
2122        }
2123
2124        impl Div<$prim_type> for Decimal {
2125            type Output = Decimal;
2126
2127            fn div(self, rhs: $prim_type) -> Self::Output {
2128                self / Decimal::from_number(rhs as f64)
2129            }
2130        }
2131
2132        impl Div<Decimal> for $prim_type {
2133            type Output = Decimal;
2134
2135            fn div(self, rhs: Decimal) -> Self::Output {
2136                Decimal::from_number(self as f64) / rhs
2137            }
2138        }
2139
2140        impl Rem<$prim_type> for Decimal {
2141            type Output = Decimal;
2142
2143            fn rem(self, rhs: $prim_type) -> Self::Output {
2144                self % Decimal::from_number(rhs as f64)
2145            }
2146        }
2147
2148        impl Rem<Decimal> for $prim_type {
2149            type Output = Decimal;
2150
2151            fn rem(self, rhs: Decimal) -> Self::Output {
2152                Decimal::from_number(self as f64) % rhs
2153            }
2154        }
2155
2156        impl AddAssign<$prim_type> for Decimal {
2157            fn add_assign(&mut self, rhs: $prim_type) {
2158                *self = *self + rhs;
2159            }
2160        }
2161
2162        impl SubAssign<$prim_type> for Decimal {
2163            fn sub_assign(&mut self, rhs: $prim_type) {
2164                *self = *self - rhs;
2165            }
2166        }
2167
2168        impl MulAssign<$prim_type> for Decimal {
2169            fn mul_assign(&mut self, rhs: $prim_type) {
2170                *self = *self * rhs;
2171            }
2172        }
2173
2174        impl DivAssign<$prim_type> for Decimal {
2175            fn div_assign(&mut self, rhs: $prim_type) {
2176                *self = *self / rhs;
2177            }
2178        }
2179
2180        impl RemAssign<$prim_type> for Decimal {
2181            fn rem_assign(&mut self, rhs: $prim_type) {
2182                *self = *self % rhs;
2183            }
2184        }
2185    };
2186}
2187
2188impl_from_primitive!(i8);
2189impl_from_primitive!(i16);
2190impl_from_primitive!(i32);
2191impl_from_primitive!(i64);
2192impl_from_primitive!(u8);
2193impl_from_primitive!(u16);
2194impl_from_primitive!(u32);
2195impl_from_primitive!(u64);
2196impl_from_primitive!(f32);
2197impl_from_primitive!(f64);
2198
2199impl_ops_primitive!(i8);
2200impl_ops_primitive!(i16);
2201impl_ops_primitive!(i32);
2202impl_ops_primitive!(i64);
2203impl_ops_primitive!(u8);
2204impl_ops_primitive!(u16);
2205impl_ops_primitive!(u32);
2206impl_ops_primitive!(u64);
2207impl_ops_primitive!(f32);
2208impl_ops_primitive!(f64);
2209
2210impl TryFrom<&str> for Decimal {
2211    type Error = BreakEternityError;
2212
2213    fn try_from(s: &str) -> Result<Self, Self::Error> {
2214        let mut value = s.to_string();
2215        if *IGNORE_COMMAS {
2216            value = value.replace(',', "");
2217        } else if *COMMAS_ARE_DECIMAL_POINTS {
2218            value = value.replace(',', ".");
2219        }
2220        let value = value.as_str();
2221
2222        let pentation_parts: Vec<&str> = value.split("^^^").collect();
2223        if pentation_parts.len() == 2 {
2224            let base = pentation_parts[0].parse::<Number>();
2225            if let Err(parse_error) = base {
2226                return Err(BreakEternityError::ParseError {
2227                    parsed: s.to_string(),
2228                    error: parse_error,
2229                });
2230            }
2231            let base = base.unwrap();
2232            let height = pentation_parts[1].parse::<Number>();
2233            if let Err(parse_error) = height {
2234                return Err(BreakEternityError::ParseError {
2235                    parsed: s.to_string(),
2236                    error: parse_error,
2237                });
2238            }
2239            let height = height.unwrap();
2240            let mut payload = 1.0;
2241            let height_parts = pentation_parts[1].split(';').collect::<Vec<&str>>();
2242            if height_parts.len() == 2 {
2243                let payload_parsed = height_parts[1].parse::<Number>();
2244                if let Err(parse_error) = payload_parsed {
2245                    return Err(BreakEternityError::ParseError {
2246                        parsed: s.to_string(),
2247                        error: parse_error,
2248                    });
2249                }
2250                payload = payload_parsed.unwrap();
2251                if !payload.is_finite() {
2252                    payload = 1.0;
2253                }
2254            }
2255
2256            if base.is_finite() && height.is_finite() {
2257                return Ok(Decimal::from_number(base)
2258                    .pentate(Some(height), Some(Decimal::from_number(payload))));
2259            }
2260        }
2261
2262        let tetration_parts: Vec<&str> = value.split("^^").collect();
2263        if tetration_parts.len() == 2 {
2264            let base = tetration_parts[0].parse::<Number>();
2265            if let Err(parse_error) = base {
2266                return Err(BreakEternityError::ParseError {
2267                    parsed: s.to_string(),
2268                    error: parse_error,
2269                });
2270            }
2271            let base = base.unwrap();
2272            let height = tetration_parts[1].parse::<Number>();
2273            if let Err(parse_error) = height {
2274                return Err(BreakEternityError::ParseError {
2275                    parsed: s.to_string(),
2276                    error: parse_error,
2277                });
2278            }
2279            let height = height.unwrap();
2280            let mut payload = 1.0;
2281            let height_parts = tetration_parts[1].split(';').collect::<Vec<&str>>();
2282            if height_parts.len() == 2 {
2283                let payload_parsed = height_parts[1].parse::<Number>();
2284                if let Err(parse_error) = payload_parsed {
2285                    return Err(BreakEternityError::ParseError {
2286                        parsed: s.to_string(),
2287                        error: parse_error,
2288                    });
2289                }
2290                payload = payload_parsed.unwrap();
2291                if !payload.is_finite() {
2292                    payload = 1.0;
2293                }
2294            }
2295
2296            if base.is_finite() && height.is_finite() {
2297                return Ok(Decimal::from_number(base)
2298                    .tetrate(Some(height), Some(Decimal::from_number(payload))));
2299            }
2300        }
2301
2302        let pow_parts = value.split('^').collect::<Vec<&str>>();
2303        if pow_parts.len() == 2 {
2304            let base = pow_parts[0].parse::<Number>();
2305            if let Err(parse_error) = base {
2306                return Err(BreakEternityError::ParseError {
2307                    parsed: s.to_string(),
2308                    error: parse_error,
2309                });
2310            }
2311            let base = base.unwrap();
2312            let exponent = pow_parts[1].parse::<Number>();
2313            if let Err(parse_error) = exponent {
2314                return Err(BreakEternityError::ParseError {
2315                    parsed: s.to_string(),
2316                    error: parse_error,
2317                });
2318            }
2319            let exponent = exponent.unwrap();
2320            if base.is_finite() && exponent.is_finite() {
2321                return Ok(Decimal::from_number(base).pow(Decimal::from_number(exponent)));
2322            }
2323        }
2324
2325        let value = value.trim().to_lowercase();
2326        let value = value.as_str();
2327
2328        let mut pt_parts = value.split("pt").collect::<Vec<&str>>();
2329        if pt_parts.len() == 2 {
2330            let base: f64 = 10.0;
2331            let height = pt_parts[0].parse::<Number>();
2332            if let Err(parse_error) = height {
2333                return Err(BreakEternityError::ParseError {
2334                    parsed: s.to_string(),
2335                    error: parse_error,
2336                });
2337            }
2338            let height = height.unwrap();
2339            let tmp = pt_parts[1].replace(['(', ')'], "");
2340            pt_parts[1] = tmp.as_str();
2341
2342            let payload = pt_parts[1].parse::<Number>();
2343            if let Err(parse_error) = payload {
2344                return Err(BreakEternityError::ParseError {
2345                    parsed: s.to_string(),
2346                    error: parse_error,
2347                });
2348            }
2349            let mut payload = payload.unwrap();
2350            if !payload.is_finite() {
2351                payload = 1.0;
2352            }
2353            if base.is_finite() && height.is_finite() {
2354                // tetrate again
2355                return Ok(Decimal::from_number(base)
2356                    .tetrate(Some(height), Some(Decimal::from_number(payload))));
2357            }
2358        }
2359
2360        let mut p_parts = value.split('p').collect::<Vec<&str>>();
2361        if p_parts.len() == 2 {
2362            let base: f64 = 10.0;
2363            let height = p_parts[0].parse::<Number>();
2364            if let Err(parse_error) = height {
2365                return Err(BreakEternityError::ParseError {
2366                    parsed: s.to_string(),
2367                    error: parse_error,
2368                });
2369            }
2370            let height = height.unwrap();
2371            let tmp = p_parts[1].replace(['(', ')'], "");
2372            p_parts[1] = tmp.as_str();
2373
2374            let payload = p_parts[1].parse::<Number>();
2375            if let Err(parse_error) = payload {
2376                return Err(BreakEternityError::ParseError {
2377                    parsed: s.to_string(),
2378                    error: parse_error,
2379                });
2380            }
2381            let mut payload = payload.unwrap();
2382            if !payload.is_finite() {
2383                payload = 1.0;
2384            }
2385            if base.is_finite() && height.is_finite() {
2386                // another tetrate
2387                return Ok(Decimal::from_number(base)
2388                    .tetrate(Some(height), Some(Decimal::from_number(payload))));
2389            }
2390        }
2391
2392        let e_parts = value.split('e').collect::<Vec<&str>>();
2393        let e_count = e_parts.len() - 1;
2394
2395        if e_count == 0 {
2396            let number_attempt = value.parse::<Number>();
2397            if let Err(parse_error) = number_attempt {
2398                return Err(BreakEternityError::ParseError {
2399                    parsed: s.to_string(),
2400                    error: parse_error,
2401                });
2402            }
2403            let number_attempt = number_attempt.unwrap();
2404            if number_attempt.is_finite() {
2405                return Ok(Decimal::default().set_from_number(number_attempt));
2406            }
2407        } else if e_count == 1 {
2408            let number_attempt = value.parse::<Number>();
2409            if let Err(parse_error) = number_attempt {
2410                return Err(BreakEternityError::ParseError {
2411                    parsed: s.to_string(),
2412                    error: parse_error,
2413                });
2414            }
2415            let number_attempt = number_attempt.unwrap();
2416            if number_attempt.is_finite() && number_attempt != 0.0 {
2417                return Ok(Decimal::default().set_from_number(number_attempt));
2418            }
2419        }
2420
2421        let new_parts = value.split("e^").collect::<Vec<&str>>();
2422        if new_parts.len() == 2 {
2423            let mut dec = Decimal {
2424                sign: 1,
2425                ..Default::default()
2426            };
2427            if new_parts[0].starts_with('-') {
2428                dec.sign = -1;
2429            }
2430
2431            let mut layer_string = "".to_string();
2432            for (i, c) in new_parts[1].chars().enumerate() {
2433                if c.is_numeric()
2434                    || c == '+'
2435                    || c == '-'
2436                    || c == '.'
2437                    || c == 'e'
2438                    || c == ','
2439                    || c == '/'
2440                {
2441                    layer_string.push(c);
2442                } else {
2443                    let layer = layer_string.parse::<Number>();
2444                    if let Err(parse_error) = layer {
2445                        return Err(BreakEternityError::ParseError {
2446                            parsed: s.to_string(),
2447                            error: parse_error,
2448                        });
2449                    }
2450                    dec.layer = layer.unwrap() as i64;
2451                    let mag = new_parts[1][i + 1..].parse::<Number>();
2452                    if let Err(parse_error) = mag {
2453                        return Err(BreakEternityError::ParseError {
2454                            parsed: s.to_string(),
2455                            error: parse_error,
2456                        });
2457                    }
2458                    let mag = mag.unwrap();
2459                    dec.mag = mag;
2460                    dec.normalize();
2461                    return Ok(dec);
2462                }
2463            }
2464        }
2465
2466        let mut dec = Decimal::default();
2467
2468        if e_count < 1 {
2469            return Ok(dec);
2470        }
2471        let mantissa = e_parts[0].parse::<Number>();
2472        if let Err(parse_error) = mantissa {
2473            return Err(BreakEternityError::ParseError {
2474                parsed: s.to_string(),
2475                error: parse_error,
2476            });
2477        }
2478        let mantissa = mantissa.unwrap();
2479        if mantissa == 0.0 {
2480            return Ok(dec);
2481        }
2482        let exponent = e_parts.last().unwrap().parse::<Number>();
2483        if let Err(parse_error) = exponent {
2484            return Err(BreakEternityError::ParseError {
2485                parsed: s.to_string(),
2486                error: parse_error,
2487            });
2488        }
2489        let mut exponent = exponent.unwrap();
2490        if e_count >= 2 {
2491            let me = e_parts[e_parts.len() - 2].parse::<Number>();
2492            if let Err(parse_error) = me {
2493                return Err(BreakEternityError::ParseError {
2494                    parsed: s.to_string(),
2495                    error: parse_error,
2496                });
2497            }
2498            let me = me.unwrap();
2499            if me.is_finite() {
2500                exponent *= sign(me) as f64;
2501                exponent += f_maglog10(me);
2502            }
2503        }
2504
2505        if !mantissa.is_finite() {
2506            dec.sign = if e_parts[0] == "-" { -1 } else { 1 };
2507            dec.layer = e_count as i64;
2508            dec.mag = exponent;
2509        } else if e_count == 1 {
2510            dec.sign = sign(mantissa);
2511            dec.layer = 1;
2512            dec.mag = exponent + mantissa.abs().log10();
2513        } else {
2514            dec.sign = sign(mantissa);
2515            dec.layer = e_count as i64;
2516            if e_count == 2 {
2517                return Ok(
2518                    Decimal::from_components(1, 2, exponent) * Decimal::from_number(mantissa)
2519                );
2520            } else {
2521                // mantissa is way too small
2522                dec.mag = exponent;
2523            }
2524        }
2525
2526        dec.normalize();
2527        Ok(dec)
2528    }
2529}