num_bigfloat/
ext.rs

1//! BigFloat number whith support of `NaN`, and `Inf`
2//! values, and implementation of `std::ops` traits.
3
4use crate::defs::{
5    BigFloatNum, Error, RoundingMode, DECIMAL_BASE, DECIMAL_BASE_LOG10, DECIMAL_MAX_EXPONENT,
6    DECIMAL_MIN_EXPONENT, DECIMAL_PARTS, DECIMAL_POSITIONS, DECIMAL_SIGN_NEG, DECIMAL_SIGN_POS,
7    I128_MAX, I128_MIN, I64_MAX, I64_MIN, U128_MAX, U64_MAX,
8};
9use crate::util::WritableBuf;
10use core::num::FpCategory;
11
12#[cfg(feature = "std")]
13use std::fmt::Write;
14
15#[cfg(not(feature = "std"))]
16use core::fmt::Write;
17
18#[cfg(feature = "rand")]
19use rand::random;
20
21#[cfg(feature = "serde")]
22use serde::{Deserialize, Serialize};
23
24/// Maximum value possible.
25pub const MAX: BigFloat = BigFloat {
26    inner: Flavor::Value(crate::defs::MAX),
27};
28
29/// Maximum possible exponent.
30pub const MAX_EXP: i8 = DECIMAL_MAX_EXPONENT;
31
32/// Minumum value possible.
33pub const MIN: BigFloat = BigFloat {
34    inner: Flavor::Value(crate::defs::MIN),
35};
36
37/// Minumum possible exponent.
38pub const MIN_EXP: i8 = DECIMAL_MIN_EXPONENT;
39
40/// The smallest positive number.
41pub const MIN_POSITIVE: BigFloat = BigFloat {
42    inner: Flavor::Value(crate::defs::MIN_POSITIVE),
43};
44
45/// The smallest positive normal number.
46pub const MIN_POSITIVE_NORMAL: BigFloat = BigFloat {
47    inner: Flavor::Value(crate::defs::MIN_POSITIVE_NORMAL),
48};
49
50/// Radix of BigFloat.
51pub const RADIX: u32 = 10;
52
53/// NaN representation.
54pub const NAN: BigFloat = BigFloat { inner: Flavor::NaN };
55
56/// Positive infinity.
57pub const INF_POS: BigFloat = BigFloat {
58    inner: Flavor::Inf(DECIMAL_SIGN_POS),
59};
60
61/// Negative infinity.
62pub const INF_NEG: BigFloat = BigFloat {
63    inner: Flavor::Inf(DECIMAL_SIGN_NEG),
64};
65
66/// Value of zero.
67pub const ZERO: BigFloat = BigFloat {
68    inner: Flavor::Value(crate::defs::ZERO),
69};
70
71/// Value of one.
72pub const ONE: BigFloat = BigFloat {
73    inner: Flavor::Value(crate::defs::ONE),
74};
75
76/// Value of two.
77pub const TWO: BigFloat = BigFloat {
78    inner: Flavor::Value(crate::defs::TWO),
79};
80
81/// Euler's number.
82pub const E: BigFloat = BigFloat {
83    inner: Flavor::Value(crate::defs::E),
84};
85
86/// PI number.
87pub const PI: BigFloat = BigFloat {
88    inner: Flavor::Value(crate::defs::PI),
89};
90
91/// PI / 2.
92pub const HALF_PI: BigFloat = BigFloat {
93    inner: Flavor::Value(BigFloatNum {
94        m: [2099, 5144, 6397, 1691, 3132, 6192, 4896, 2679, 7963, 1570],
95        n: DECIMAL_POSITIONS as i16,
96        sign: DECIMAL_SIGN_POS,
97        e: -(DECIMAL_POSITIONS as i8 - 1),
98    }),
99};
100
101/// SQRT(2)
102pub const SQRT_2: BigFloat = BigFloat {
103    inner: Flavor::Value(BigFloatNum {
104        sign: 1,
105        e: -(DECIMAL_POSITIONS as i8) + 1,
106        n: DECIMAL_POSITIONS as i16,
107        m: [8570, 9807, 2096, 8724, 168, 488, 3095, 6237, 2135, 1414],
108    }),
109};
110
111/// 1 / PI
112pub const FRAC_1_PI: BigFloat = BigFloat {
113    inner: Flavor::Value(BigFloatNum {
114        sign: 1,
115        e: -(DECIMAL_POSITIONS as i8),
116        n: DECIMAL_POSITIONS as i16,
117        m: [689, 8724, 4502, 5267, 7767, 7153, 7906, 6183, 988, 3183],
118    }),
119};
120
121/// 1 / SQRT(2)
122pub const FRAC_1_SQRT_2: BigFloat = BigFloat {
123    inner: Flavor::Value(BigFloatNum {
124        sign: 1,
125        e: -(DECIMAL_POSITIONS as i8),
126        n: DECIMAL_POSITIONS as i16,
127        m: [2848, 9039, 484, 3621, 844, 2440, 5475, 1186, 678, 7071],
128    }),
129};
130
131/// 2 / PI
132pub const FRAC_2_PI: BigFloat = BigFloat {
133    inner: Flavor::Value(BigFloatNum {
134        sign: 1,
135        e: -(DECIMAL_POSITIONS as i8),
136        n: DECIMAL_POSITIONS as i16,
137        m: [1378, 7448, 9005, 534, 5535, 4307, 5813, 2367, 1977, 6366],
138    }),
139};
140
141/// 2 / SQRT(PI)
142pub const FRAC_2_SQRT_PI: BigFloat = BigFloat {
143    inner: Flavor::Value(BigFloatNum {
144        sign: 1,
145        e: -(DECIMAL_POSITIONS as i8) + 1,
146        n: DECIMAL_POSITIONS as i16,
147        m: [1688, 4517, 1215, 8903, 9615, 5738, 5512, 6709, 3791, 1128],
148    }),
149};
150
151/// PI / 3
152pub const FRAC_PI_3: BigFloat = BigFloat {
153    inner: Flavor::Value(BigFloatNum {
154        sign: 1,
155        e: -(DECIMAL_POSITIONS as i8) + 1,
156        n: DECIMAL_POSITIONS as i16,
157        m: [8066, 6762, 931, 4461, 5421, 7461, 6597, 5119, 1975, 1047],
158    }),
159};
160
161/// PI / 4
162pub const FRAC_PI_4: BigFloat = BigFloat {
163    inner: Flavor::Value(BigFloatNum {
164        sign: 1,
165        e: -(DECIMAL_POSITIONS as i8),
166        n: DECIMAL_POSITIONS as i16,
167        m: [493, 5721, 1987, 8458, 5660, 961, 4483, 3397, 9816, 7853],
168    }),
169};
170
171/// PI / 6
172pub const FRAC_PI_6: BigFloat = BigFloat {
173    inner: Flavor::Value(BigFloatNum {
174        sign: 1,
175        e: -(DECIMAL_POSITIONS as i8),
176        n: DECIMAL_POSITIONS as i16,
177        m: [329, 3814, 4658, 2305, 7107, 7307, 2988, 5598, 9877, 5235],
178    }),
179};
180
181/// PI / 8
182pub const FRAC_PI_8: BigFloat = BigFloat {
183    inner: Flavor::Value(BigFloatNum {
184        sign: 1,
185        e: -(DECIMAL_POSITIONS as i8),
186        n: DECIMAL_POSITIONS as i16,
187        m: [5246, 7860, 993, 4229, 7830, 5480, 7241, 1698, 9908, 3926],
188    }),
189};
190
191/// ln(10)
192pub const LN_10: BigFloat = BigFloat {
193    inner: Flavor::Value(BigFloatNum {
194        sign: 1,
195        e: -(DECIMAL_POSITIONS as i8) + 1,
196        n: DECIMAL_POSITIONS as i16,
197        m: [7601, 6420, 6843, 1454, 1799, 6840, 4045, 9299, 5850, 2302],
198    }),
199};
200
201/// ln(2)
202pub const LN_2: BigFloat = BigFloat {
203    inner: Flavor::Value(BigFloatNum {
204        sign: 1,
205        e: -(DECIMAL_POSITIONS as i8),
206        n: DECIMAL_POSITIONS as i16,
207        m: [755, 6568, 5817, 1214, 7232, 941, 9453, 559, 4718, 6931],
208    }),
209};
210
211/// log10(E)
212pub const LOG10_E: BigFloat = BigFloat {
213    inner: Flavor::Value(BigFloatNum {
214        sign: 1,
215        e: -(DECIMAL_POSITIONS as i8),
216        n: DECIMAL_POSITIONS as i16,
217        m: [2944, 5082, 1660, 9189, 1128, 2765, 2518, 1903, 9448, 4342],
218    }),
219};
220
221/// log2(E)
222pub const LOG2_E: BigFloat = BigFloat {
223    inner: Flavor::Value(BigFloatNum {
224        sign: 1,
225        e: -(DECIMAL_POSITIONS as i8) + 1,
226        n: DECIMAL_POSITIONS as i16,
227        m: [7427, 9213, 18, 4681, 5992, 4073, 8963, 4088, 6950, 1442],
228    }),
229};
230
231/// The difference between 1 and the smallest floating point number greater than 1.
232pub const EPSILON: BigFloat = BigFloat {
233    inner: Flavor::Value(BigFloatNum {
234        sign: 1,
235        e: 1 - DECIMAL_POSITIONS as i8,
236        n: 1,
237        m: [1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
238    }),
239};
240
241/// 180 / PI
242#[cfg(not(feature = "std"))]
243#[cfg(feature = "num-traits")]
244pub const RAD_TO_DEG_FACTOR: BigFloat = BigFloat {
245    inner: Flavor::Value(BigFloatNum {
246        sign: 1,
247        e: -(DECIMAL_POSITIONS as i8) + 2,
248        n: DECIMAL_POSITIONS as i16,
249        m: [3240, 1703, 4105, 5481, 7981, 876, 8232, 5130, 5779, 5729],
250    }),
251};
252
253/// Number representation.
254#[derive(Copy, Clone, Debug)]
255#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
256pub struct BigFloat {
257    inner: Flavor,
258}
259
260#[derive(Copy, Clone, Debug)]
261#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
262enum Flavor {
263    Value(BigFloatNum),
264    NaN,
265    Inf(i8), // signed Inf
266}
267
268impl BigFloat {
269    /// Returns a new BigFloat with the value of zero.
270    pub fn new() -> Self {
271        BigFloat {
272            inner: Flavor::Value(BigFloatNum::new()),
273        }
274    }
275
276    /// Creates a BigFloat value from a sequence of `bytes`. Each byte must represent a decimal digit.
277    /// First byte is the most significant. `bytes` can be of any length.
278    /// If `bytes` is longer than required, then the remaining bytes are ignored.
279    /// If the "sign" is negative, then the resulting BigFloat will be negative.
280    ///
281    /// ## Examples
282    ///
283    /// ```
284    /// # use num_bigfloat::BigFloat;
285    /// let n1 = BigFloat::from_bytes(&[1,2,3,4,2,0,0,0], 1, -3);
286    /// let n2 = BigFloat::from_u32(12342);
287    /// assert!(n1.cmp(&n2) == Some(0));
288    /// ```
289    pub fn from_bytes(bytes: &[u8], sign: i8, exponent: i8) -> Self {
290        BigFloat {
291            inner: Flavor::Value(BigFloatNum::from_bytes(bytes, sign, exponent)),
292        }
293    }
294
295    /// Creates a BigFloat from f64.
296    /// The conversion is not guaranteed to be lossless since BigFloat and f64 have different bases.
297    pub fn from_f64(f: f64) -> Self {
298        #[cfg(feature = "std")]
299        {
300            let strepr = format!("{:e}", f);
301            Self::parse(&strepr).unwrap()
302        }
303        #[cfg(not(feature = "std"))]
304        {
305            let mut buf = [0u8; 64];
306            let mut strepr = WritableBuf::new(&mut buf); // sign + number + dot + "e" + sign + exponent
307            write!(strepr, "{:e}", f).unwrap();
308            Self::parse(core::str::from_utf8(&buf).unwrap()).unwrap()
309        }
310    }
311
312    /// Creates a BigFloat from f32.
313    /// The conversion is not guaranteed to be lossless since BigFloat and f64 have different bases.
314    pub fn from_f32(f: f32) -> Self {
315        Self::from_f64(f as f64)
316    }
317
318    /// Converts BigFloat to f64.
319    pub fn to_f64(&self) -> f64 {
320        match self.inner {
321            Flavor::Value(_) => {
322                let mut buf = [0; 64];
323                let mut w = WritableBuf::new(&mut buf);
324                self.write_str(&mut w).unwrap();
325                let written_len = w.len();
326                let s = core::str::from_utf8(&buf[0..written_len]).unwrap();
327                str::parse::<f64>(s).unwrap()
328            }
329            Flavor::Inf(s) => {
330                if s == DECIMAL_SIGN_POS {
331                    f64::INFINITY
332                } else {
333                    f64::NEG_INFINITY
334                }
335            }
336            Flavor::NaN => f64::NAN,
337        }
338    }
339
340    /// Converts BigFloat to f32.
341    pub fn to_f32(&self) -> f32 {
342        self.to_f64() as f32
343    }
344
345    /// Converts BigFloat to i64.
346    /// The function retursn None if `self` is Inf, NaN, or out of range of i64.
347    pub fn to_i64(&self) -> Option<i64> {
348        self.to_int::<i64>(&I64_MIN, &I64_MAX)
349    }
350
351    /// Converts BigFloat to i128.
352    /// The function retursn None if `self` is Inf, NaN, or out of range of i128.
353    pub fn to_i128(&self) -> Option<i128> {
354        self.to_int::<i128>(&I128_MIN, &I128_MAX)
355    }
356
357    /// Converts absolute value of `self` to u64.
358    /// The function retursn None if `self` is Inf, NaN, or out of range of u64.
359    pub fn to_u64(&self) -> Option<u64> {
360        self.to_uint::<u64>(&U64_MAX)
361    }
362
363    /// Converts absolute value of `self` to u128.
364    /// The function retursn None if `self` is Inf, NaN, or out of range of u128.
365    pub fn to_u128(&self) -> Option<u128> {
366        self.to_uint::<u128>(&U128_MAX)
367    }
368
369    fn to_int<T>(&self, min: &BigFloatNum, max: &BigFloatNum) -> Option<T>
370    where
371        T: core::ops::DivAssign<T>
372            + core::ops::AddAssign<T>
373            + core::ops::MulAssign<T>
374            + core::ops::SubAssign<T>
375            + core::convert::From<u32>
376            + core::convert::From<i16>,
377    {
378        match self.inner {
379            Flavor::Value(v) => {
380                let int = v.int();
381
382                if int.cmp(min) >= 0 && int.cmp(max) <= 0 {
383                    let mut ret: T = 0i16.into();
384                    let mut n = int.n as usize + DECIMAL_BASE_LOG10 - 1;
385                    n /= DECIMAL_BASE_LOG10;
386                    let mut miter = int.m[..n].iter().rev();
387                    n *= DECIMAL_BASE_LOG10;
388                    n = (n as i16 + int.e as i16) as usize;
389
390                    while n >= DECIMAL_BASE_LOG10 {
391                        ret *= (DECIMAL_BASE as u32).into();
392                        if v.sign == DECIMAL_SIGN_POS {
393                            ret += (*miter.next().unwrap()).into();
394                        } else {
395                            ret -= (*miter.next().unwrap()).into();
396                        }
397                        n -= DECIMAL_BASE_LOG10;
398                    }
399
400                    if n > 0 {
401                        let mut d: T = (DECIMAL_BASE as u32).into();
402                        while n > 0 {
403                            d /= 10i16.into();
404                            n -= 1;
405                        }
406                        let mut p: T = (*miter.next().unwrap()).into();
407                        p /= d;
408                        if v.sign == DECIMAL_SIGN_POS {
409                            ret += p;
410                        } else {
411                            ret -= p;
412                        }
413                    }
414
415                    Some(ret)
416                } else {
417                    None
418                }
419            }
420            Flavor::Inf(_) => None,
421            Flavor::NaN => None,
422        }
423    }
424
425    fn to_uint<T>(&self, max: &BigFloatNum) -> Option<T>
426    where
427        T: core::ops::DivAssign<T>
428            + core::ops::AddAssign<T>
429            + core::ops::MulAssign<T>
430            + core::convert::From<u32>
431            + core::convert::From<u16>,
432    {
433        match self.inner {
434            Flavor::Value(v) => {
435                let int = v.int().abs();
436
437                if int.cmp(max) <= 0 {
438                    let mut ret: T = 0u16.into();
439                    let mut n = int.n as usize + DECIMAL_BASE_LOG10 - 1;
440                    n /= DECIMAL_BASE_LOG10;
441                    let mut miter = int.m[..n].iter().rev();
442                    n *= DECIMAL_BASE_LOG10;
443                    n = (n as i16 + int.e as i16) as usize;
444
445                    while n >= DECIMAL_BASE_LOG10 {
446                        ret *= (DECIMAL_BASE as u32).into();
447                        ret += (*miter.next().unwrap() as u16).into();
448                        n -= DECIMAL_BASE_LOG10;
449                    }
450
451                    if n > 0 {
452                        let mut d: T = (DECIMAL_BASE as u32).into();
453                        while n > 0 {
454                            d /= 10u16.into();
455                            n -= 1;
456                        }
457                        let mut p: T = (*miter.next().unwrap() as u16).into();
458                        p /= d;
459                        ret += p;
460                    }
461
462                    Some(ret)
463                } else {
464                    None
465                }
466            }
467            Flavor::Inf(_) => None,
468            Flavor::NaN => None,
469        }
470    }
471
472    /// Returns the mantissa of the BigFloat in `bytes`. Each byte represents a decimal digit.
473    /// The first byte is the most significant. `bytes` can be of any length.
474    /// If the length of `bytes` is less than the number of decimal positions filled in the mantissa,
475    /// then the rest of the mantissa will be omitted.
476    ///
477    /// The length of the mantissa can be determined using `get_mantissa_len`.
478    /// If `self` is Inf or NaN, nothing is returned.
479    ///
480    /// ## Examples
481    ///
482    /// ```
483    /// # use num_bigfloat::BigFloat;
484    /// let n = BigFloat::from_f64(123.42);
485    /// let mut m = [0; 40];
486    /// n.get_mantissa_bytes(&mut m);
487    /// // compare m[0..10] to [1,2,3,4,2,0,0,0,0,0]
488    /// assert!(m[0..10].iter().zip([1,2,3,4,2,0,0,0,0,0].iter()).filter(|x| { x.0 != x.1 }).count() == 0);
489    /// ```
490    pub fn get_mantissa_bytes(&self, bytes: &mut [u8]) {
491        if let Flavor::Value(v) = self.inner {
492            v.get_mantissa_bytes(bytes);
493        }
494    }
495
496    /// Returns the number of decimal places filled in the mantissa.
497    /// If `self` is Inf or NaN, 0 is returned.
498    pub fn get_mantissa_len(&self) -> usize {
499        match self.inner {
500            Flavor::Value(v) => v.get_mantissa_len(),
501            _ => 0,
502        }
503    }
504
505    /// Returns 1 if BigFloat is positive, -1 otherwise.
506    /// If `self` is NaN, 0 is returned.
507    pub fn get_sign(&self) -> i8 {
508        match self.inner {
509            Flavor::Value(v) => v.sign,
510            Flavor::Inf(s) => s,
511            _ => 0,
512        }
513    }
514
515    /// Returns the exponent part of the number.
516    /// If `self` is Inf or NaN, 0 is returned.
517    pub fn get_exponent(&self) -> i8 {
518        match self.inner {
519            Flavor::Value(v) => v.e,
520            _ => 0,
521        }
522    }
523
524    /// Sets the exponent part of the number.
525    /// The function has no effect on Inf and NaN values.
526    pub fn set_exponent(&mut self, e: i8) {
527        if let Flavor::Value(mut v) = self.inner {
528            v.e = e;
529            self.inner = Flavor::Value(v);
530        }
531    }
532
533    /// Returns the raw parts of the number: the mantissa, the number of decimal places in the mantissa,
534    /// the sign, and the exponent.
535    /// If `self` is Inf or NaN, None is returned.
536    pub fn to_raw_parts(&self) -> Option<([i16; DECIMAL_PARTS], i16, i8, i8)> {
537        match self.inner {
538            Flavor::Value(v) => Some((v.m, v.n, v.sign, v.e)),
539            _ => None,
540        }
541    }
542
543    /// Creates a BigFloat from the raw parts. `to_raw_parts` can be used to get the raw parts of a number.
544    pub fn from_raw_parts(
545        mantissa: [i16; DECIMAL_PARTS],
546        mantissa_len: i16,
547        sign: i8,
548        exponent: i8,
549    ) -> Self {
550        let val = BigFloatNum {
551            sign,
552            e: exponent,
553            n: mantissa_len,
554            m: mantissa,
555        };
556        BigFloat {
557            inner: Flavor::Value(val),
558        }
559    }
560
561    /// Returns true if `self` is positive infinity.
562    pub fn is_inf_pos(&self) -> bool {
563        matches!(self.inner, Flavor::Inf(DECIMAL_SIGN_POS))
564    }
565
566    /// Returns true if `self` is negative infinity.
567    pub fn is_inf_neg(&self) -> bool {
568        matches!(self.inner, Flavor::Inf(DECIMAL_SIGN_NEG))
569    }
570
571    /// Returns true if `self` is infinite.
572    pub fn is_inf(&self) -> bool {
573        self.is_inf_pos() || self.is_inf_neg()
574    }
575
576    /// Return true if `self` is not a number.
577    pub fn is_nan(&self) -> bool {
578        matches!(self.inner, Flavor::NaN)
579    }
580
581    /// Adds `d2` to `self` and returns the result of the addition.
582    pub fn add(&self, d2: &Self) -> Self {
583        match self.inner {
584            Flavor::Value(v1) => match d2.inner {
585                Flavor::Value(v2) => {
586                    Self::result_to_ext(v1.add(&v2), v1.is_zero(), v1.sign == v2.sign)
587                }
588                Flavor::Inf(s2) => BigFloat {
589                    inner: Flavor::Inf(s2),
590                },
591                Flavor::NaN => NAN,
592            },
593            Flavor::Inf(s1) => match d2.inner {
594                Flavor::Value(_) => BigFloat {
595                    inner: Flavor::Inf(s1),
596                },
597                Flavor::Inf(s2) => {
598                    if s1 != s2 {
599                        NAN
600                    } else {
601                        BigFloat {
602                            inner: Flavor::Inf(s2),
603                        }
604                    }
605                }
606                Flavor::NaN => NAN,
607            },
608            Flavor::NaN => NAN,
609        }
610    }
611
612    /// Subtracts `d2` from `self` and return the result of the subtraction.
613    pub fn sub(&self, d2: &Self) -> Self {
614        match self.inner {
615            Flavor::Value(v1) => match d2.inner {
616                Flavor::Value(v2) => {
617                    Self::result_to_ext(v1.sub(&v2), v1.is_zero(), v1.sign == v2.sign)
618                }
619                Flavor::Inf(s2) => {
620                    if s2 == DECIMAL_SIGN_POS {
621                        INF_NEG
622                    } else {
623                        INF_POS
624                    }
625                }
626                Flavor::NaN => NAN,
627            },
628            Flavor::Inf(s1) => match d2.inner {
629                Flavor::Value(_) => BigFloat {
630                    inner: Flavor::Inf(s1),
631                },
632                Flavor::Inf(s2) => {
633                    if s1 == s2 {
634                        NAN
635                    } else {
636                        BigFloat {
637                            inner: Flavor::Inf(s1),
638                        }
639                    }
640                }
641                Flavor::NaN => NAN,
642            },
643            Flavor::NaN => NAN,
644        }
645    }
646
647    /// Multiplies `self` by `d2` and returns the result of the multiplication.
648    pub fn mul(&self, d2: &Self) -> Self {
649        match self.inner {
650            Flavor::Value(v1) => {
651                match d2.inner {
652                    Flavor::Value(v2) => {
653                        Self::result_to_ext(v1.mul(&v2), v1.is_zero(), v1.sign == v2.sign)
654                    }
655                    Flavor::Inf(s2) => {
656                        if v1.is_zero() {
657                            // 0*inf
658                            NAN
659                        } else {
660                            let s = if v1.sign == s2 { DECIMAL_SIGN_POS } else { DECIMAL_SIGN_NEG };
661                            BigFloat {
662                                inner: Flavor::Inf(s),
663                            }
664                        }
665                    }
666                    Flavor::NaN => NAN,
667                }
668            }
669            Flavor::Inf(s1) => {
670                match d2.inner {
671                    Flavor::Value(v2) => {
672                        if v2.is_zero() {
673                            // inf*0
674                            NAN
675                        } else {
676                            let s = if v2.sign == s1 { DECIMAL_SIGN_POS } else { DECIMAL_SIGN_NEG };
677                            BigFloat {
678                                inner: Flavor::Inf(s),
679                            }
680                        }
681                    }
682                    Flavor::Inf(s2) => {
683                        let s = if s1 == s2 { DECIMAL_SIGN_POS } else { DECIMAL_SIGN_NEG };
684                        BigFloat {
685                            inner: Flavor::Inf(s),
686                        }
687                    }
688                    Flavor::NaN => NAN,
689                }
690            }
691            Flavor::NaN => NAN,
692        }
693    }
694
695    /// Divides `self` by `d2` and returns the result of the division.
696    pub fn div(&self, d2: &Self) -> Self {
697        match self.inner {
698            Flavor::Value(v1) => match d2.inner {
699                Flavor::Value(v2) => {
700                    Self::result_to_ext(v1.div(&v2), v1.is_zero(), v1.sign == v2.sign)
701                }
702                Flavor::Inf(_) => ZERO,
703                Flavor::NaN => NAN,
704            },
705            Flavor::Inf(s1) => match d2.inner {
706                Flavor::Value(v) => {
707                    if s1 == v.sign {
708                        INF_POS
709                    } else {
710                        INF_NEG
711                    }
712                }
713                Flavor::Inf(_) => NAN,
714                Flavor::NaN => NAN,
715            },
716            Flavor::NaN => NAN,
717        }
718    }
719
720    /// Compares `self` to `d2`.
721    /// Returns positive if `self` > `d2`, negative if `self` < `d2`, zero if `self` == `d2`, None if `self` or `d2` is NaN.
722    pub fn cmp(&self, d2: &BigFloat) -> Option<i16> {
723        match self.inner {
724            Flavor::Value(v1) => match d2.inner {
725                Flavor::Value(v2) => Some(v1.cmp(&v2)),
726                Flavor::Inf(s2) => {
727                    if s2 == DECIMAL_SIGN_POS {
728                        Some(-1)
729                    } else {
730                        Some(1)
731                    }
732                }
733                Flavor::NaN => None,
734            },
735            Flavor::Inf(s1) => match d2.inner {
736                Flavor::Value(_) => Some(s1 as i16),
737                Flavor::Inf(s2) => Some((s1 - s2) as i16),
738                Flavor::NaN => None,
739            },
740            Flavor::NaN => None,
741        }
742    }
743
744    /// Reverses the sign of a number.
745    pub fn inv_sign(&self) -> BigFloat {
746        match self.inner {
747            Flavor::Value(mut v1) => {
748                if v1.sign == DECIMAL_SIGN_POS {
749                    v1.sign = DECIMAL_SIGN_NEG;
750                } else {
751                    v1.sign = DECIMAL_SIGN_POS;
752                }
753                BigFloat {
754                    inner: Flavor::Value(v1),
755                }
756            }
757            Flavor::Inf(s1) => {
758                if s1 == DECIMAL_SIGN_POS {
759                    INF_NEG
760                } else {
761                    INF_POS
762                }
763            }
764            Flavor::NaN => NAN,
765        }
766    }
767
768    /// Returns `self` to the power of `d1`.
769    pub fn pow(&self, d1: &Self) -> Self {
770        match self.inner {
771            Flavor::Value(v1) => {
772                match d1.inner {
773                    Flavor::Value(v2) => {
774                        Self::result_to_ext(v1.pow(&v2), v1.is_zero(), v1.sign == v2.sign)
775                    }
776                    Flavor::Inf(s2) => {
777                        // v1^inf
778                        let val = v1.cmp(&BigFloatNum::one());
779                        if val > 0 {
780                            BigFloat {
781                                inner: Flavor::Inf(s2),
782                            }
783                        } else if val < 0 {
784                            ZERO
785                        } else {
786                            ONE
787                        }
788                    }
789                    Flavor::NaN => NAN,
790                }
791            }
792            Flavor::Inf(s1) => {
793                match d1.inner {
794                    Flavor::Value(v2) => {
795                        // inf ^ v2
796                        let val = v2.cmp(&BigFloatNum::new());
797                        if val > 0 {
798                            if s1 == DECIMAL_SIGN_NEG && v2.frac().is_zero() && !v2.is_int_even() {
799                                // v2 is odd without fractional part.
800                                INF_NEG
801                            } else {
802                                INF_POS
803                            }
804                        } else if val < 0 {
805                            ZERO
806                        } else {
807                            ONE
808                        }
809                    }
810                    Flavor::Inf(s2) => {
811                        // inf^inf
812                        if s2 == DECIMAL_SIGN_POS {
813                            INF_POS
814                        } else {
815                            ZERO
816                        }
817                    }
818                    Flavor::NaN => NAN,
819                }
820            }
821            Flavor::NaN => NAN,
822        }
823    }
824
825    /// Returns the logarithm base `b` of a number.
826    pub fn log(&self, b: &Self) -> Self {
827        match self.inner {
828            Flavor::Value(v1) => {
829                match b.inner {
830                    Flavor::Value(v2) => Self::result_to_ext(v1.log(&v2), false, true),
831                    Flavor::Inf(s2) => {
832                        // v1.log(inf)
833                        if s2 == DECIMAL_SIGN_POS {
834                            ZERO
835                        } else {
836                            NAN
837                        }
838                    }
839                    Flavor::NaN => NAN,
840                }
841            }
842            Flavor::Inf(s1) => {
843                if s1 == DECIMAL_SIGN_NEG {
844                    // -inf.log(any)
845                    NAN
846                } else {
847                    match b.inner {
848                        Flavor::Value(v2) => {
849                            // +inf.log(v2)
850                            let val = v2.cmp(&BigFloatNum::one());
851                            if val < 0 {
852                                INF_NEG
853                            } else {
854                                INF_POS
855                            }
856                        }
857                        Flavor::Inf(_) => NAN, // +inf.log(inf)
858                        Flavor::NaN => NAN,
859                    }
860                }
861            }
862            Flavor::NaN => NAN,
863        }
864    }
865
866    fn result_to_ext(
867        res: Result<BigFloatNum, Error>,
868        is_dividend_zero: bool,
869        is_same_sign: bool,
870    ) -> BigFloat {
871        match res {
872            Err(e) => match e {
873                Error::ExponentOverflow(s) => {
874                    if s == DECIMAL_SIGN_POS {
875                        INF_POS
876                    } else {
877                        INF_NEG
878                    }
879                }
880                Error::DivisionByZero => {
881                    if is_dividend_zero {
882                        NAN
883                    } else if is_same_sign {
884                        INF_POS
885                    } else {
886                        INF_NEG
887                    }
888                }
889                Error::ArgumentIsNegative => NAN,
890                Error::InvalidArgument => NAN,
891            },
892            Ok(v) => BigFloat {
893                inner: Flavor::Value(v),
894            },
895        }
896    }
897
898    /// Returns true if `self` is positive.
899    /// The function returns false if `self` is NaN.
900    pub fn is_positive(&self) -> bool {
901        match self.inner {
902            Flavor::Value(v) => v.sign == DECIMAL_SIGN_POS,
903            Flavor::Inf(s) => s == DECIMAL_SIGN_POS,
904            Flavor::NaN => false,
905        }
906    }
907
908    /// Returns true if `self` is negative.
909    /// The function returns false if `self` is NaN.
910    pub fn is_negative(&self) -> bool {
911        match self.inner {
912            Flavor::Value(v) => v.sign == DECIMAL_SIGN_NEG,
913            Flavor::Inf(s) => s == DECIMAL_SIGN_NEG,
914            Flavor::NaN => false,
915        }
916    }
917
918    /// Returns true if `self` is subnormal.
919    /// A number is considered subnormal if not all digits of the mantissa are used, and the exponent has the minimum possible value.
920    pub fn is_subnormal(&self) -> bool {
921        if let Flavor::Value(v) = self.inner {
922            return v.is_subnormal();
923        }
924        false
925    }
926
927    /// Returns true if `self` is zero.
928    pub fn is_zero(&self) -> bool {
929        match self.inner {
930            Flavor::Value(v) => v.is_zero(),
931            Flavor::Inf(_) => false,
932            Flavor::NaN => false,
933        }
934    }
935
936    /// Restricts the value of `self` to an interval determined by the values of `min` and `max`.
937    /// The function returns `max` if `self` is greater than `max`, `min` if `self` is less than `min`, and `self` otherwise.
938    /// If either argument is NaN or `min` is greater than `max`, the function returns NaN.
939    pub fn clamp(&self, min: &Self, max: &Self) -> Self {
940        if self.is_nan() || min.is_nan() || max.is_nan() || max.cmp(min).unwrap() < 0 {
941            NAN
942        } else if self.cmp(min).unwrap() < 0 {
943            *min
944        } else if self.cmp(max).unwrap() > 0 {
945            *max
946        } else {
947            *self
948        }
949    }
950
951    /// Returns the value of `d1` if `d1` is greater than `self`, or the value of `self` otherwise.
952    /// If either argument is NaN, the function returns NaN.
953    pub fn max(&self, d1: &Self) -> Self {
954        if self.is_nan() || d1.is_nan() {
955            NAN
956        } else if self.cmp(d1).unwrap() < 0 {
957            *d1
958        } else {
959            *self
960        }
961    }
962
963    /// Returns value of `d1` if `d1` is less than `self`, or the value of `self` otherwise.
964    /// If either argument is NaN, the function returns NaN.
965    pub fn min(&self, d1: &Self) -> Self {
966        if self.is_nan() || d1.is_nan() {
967            NAN
968        } else if self.cmp(d1).unwrap() > 0 {
969            *d1
970        } else {
971            *self
972        }
973    }
974
975    /// Returns a BigFloat with the value -1 if `self` is negative, 1 if `self` is positive, zero otherwise.
976    /// The function returns NaN If `self` is NaN.
977    pub fn signum(&self) -> Self {
978        if self.is_nan() {
979            NAN
980        } else if self.is_negative() {
981            ONE.inv_sign()
982        } else {
983            ONE
984        }
985    }
986
987    /// Parses a number from the string `s`.
988    /// The function expects `s` to be a number in scientific format in base 10, or +-Inf, or NaN.
989    ///
990    /// # Examples
991    ///
992    /// ```
993    /// use num_bigfloat::BigFloat;
994    ///
995    /// let n = BigFloat::parse("0.0").unwrap();
996    /// assert!(n.to_f64() == 0.0);
997    /// let n = BigFloat::parse("1.123e-123").unwrap();
998    /// assert!((n.to_f64() - 1.123e-123).abs() < f64::EPSILON);
999    /// let n = BigFloat::parse("-Inf").unwrap();
1000    /// assert!(n.to_f64() == f64::NEG_INFINITY);
1001    /// let n = BigFloat::parse("NaN").unwrap();
1002    /// assert!(n.to_f64().is_nan());
1003    /// ```
1004    pub fn parse(s: &str) -> Option<Self> {
1005        let ps = crate::parser::parse(s);
1006        if ps.is_valid() {
1007            if ps.is_inf() {
1008                if ps.sign() == DECIMAL_SIGN_POS {
1009                    Some(INF_POS)
1010                } else {
1011                    Some(INF_NEG)
1012                }
1013            } else if ps.is_nan() {
1014                Some(NAN)
1015            } else {
1016                let (m, _n, s, e) = ps.raw_parts();
1017                let mut num = BigFloatNum::from_bytes(&m, s, 0);
1018                if num.n == 0 {
1019                    return Some(ZERO);
1020                }
1021                if e < DECIMAL_MIN_EXPONENT as i32 {
1022                    if e > DECIMAL_MIN_EXPONENT as i32 - num.n as i32 {
1023                        BigFloatNum::shift_right(
1024                            &mut num.m,
1025                            (DECIMAL_MIN_EXPONENT as i32 - e) as usize,
1026                        );
1027                        num.n = (num.n as i32 - DECIMAL_MIN_EXPONENT as i32 + e) as i16;
1028                        num.e = DECIMAL_MIN_EXPONENT;
1029                    } else {
1030                        return Some(ZERO);
1031                    }
1032                } else if e > DECIMAL_MAX_EXPONENT as i32 {
1033                    return Some(BigFloat {
1034                        inner: Flavor::Inf(s),
1035                    });
1036                } else {
1037                    num.e = e as i8;
1038                }
1039                Some(BigFloat {
1040                    inner: Flavor::Value(num),
1041                })
1042            }
1043        } else {
1044            None
1045        }
1046    }
1047
1048    pub(crate) fn write_str<T: Write>(&self, w: &mut T) -> Result<(), core::fmt::Error> {
1049        match self.inner {
1050            Flavor::Value(v) => {
1051                if v.is_zero() {
1052                    w.write_str("0.0")
1053                } else {
1054                    let part1 = if v.sign == DECIMAL_SIGN_NEG { "-" } else { "" };
1055                    let mut bytes = [0; DECIMAL_POSITIONS];
1056                    v.get_mantissa_bytes(&mut bytes);
1057                    let len = v.get_mantissa_len();
1058                    let mut part2 = [48u8; DECIMAL_POSITIONS + 1];
1059                    part2[0] = bytes[0] + 48;
1060                    part2[1] = 46;
1061                    for i in 1..len {
1062                        part2[i + 1] = bytes[i] + 48;
1063                    }
1064                    let part2: &str = core::str::from_utf8_mut(&mut part2).unwrap();
1065                    let mut buf = [0u8; 64];
1066                    let s = crate::util::concat_str(&mut buf, &[part1, part2]);
1067                    let e = v.n as i32 + v.e as i32 - 1;
1068                    if e != 0 {
1069                        let exp_sign = if e > 0 { "+" } else { "" };
1070                        w.write_fmt(format_args!("{}e{}{}", s, exp_sign, e))
1071                    } else {
1072                        w.write_str(s)
1073                    }
1074                }
1075            }
1076            Flavor::Inf(sign) => {
1077                let s = if sign == DECIMAL_SIGN_NEG { "-Inf" } else { "Inf" };
1078                w.write_str(s)
1079            }
1080            crate::ext::Flavor::NaN => w.write_str("NaN"),
1081        }
1082    }
1083
1084    /// Returns a random normalized (not subnormal) BigFloat number with exponent in the range
1085    /// from `exp_from` to `exp_to` inclusive. The sign can be positive and negative. Zero is excluded.
1086    /// Function does not follow any specific distribution law.
1087    /// The intended use of this function is for testing.
1088    ///
1089    /// # Errors
1090    ///
1091    /// InvalidArgument - when `exp_from` is greater than `exp_to`.
1092    #[cfg(feature = "rand")]
1093    pub fn random_normal(exp_from: i8, exp_to: i8) -> Result<Self, Error> {
1094        if exp_from > exp_to {
1095            return Err(Error::InvalidArgument);
1096        }
1097
1098        // build mantissa
1099        let mut mantissa = [0i16; DECIMAL_PARTS];
1100        for v in mantissa.iter_mut() {
1101            *v = (random::<u16>() % crate::defs::DECIMAL_BASE as u16) as i16;
1102        }
1103
1104        if mantissa[DECIMAL_PARTS - 1] == 0 {
1105            mantissa[DECIMAL_PARTS - 1] = (crate::defs::DECIMAL_BASE - 1) as i16;
1106        }
1107
1108        while mantissa[DECIMAL_PARTS - 1] / 1000 == 0 {
1109            mantissa[DECIMAL_PARTS - 1] *= 10;
1110        }
1111
1112        // sign & exponent
1113        let sign = if random::<i8>() & 1 == 0 { DECIMAL_SIGN_POS } else { DECIMAL_SIGN_NEG };
1114        let exp_range = exp_to as i32 - exp_from as i32;
1115        let exp = (if exp_range != 0 { random::<i32>().abs() % exp_range } else { 0 }
1116            + exp_from as i32) as i8;
1117
1118        Ok(BigFloat::from_raw_parts(
1119            mantissa,
1120            DECIMAL_POSITIONS as i16,
1121            sign,
1122            exp,
1123        ))
1124    }
1125
1126    /// Returns category of `self` as defined by `core::num::FpCategory`.
1127    pub fn classify(&self) -> FpCategory {
1128        match self.inner {
1129            Flavor::Value(v) => {
1130                if v.is_subnormal() {
1131                    FpCategory::Subnormal
1132                } else if v.is_zero() {
1133                    FpCategory::Zero
1134                } else {
1135                    FpCategory::Normal
1136                }
1137            }
1138            Flavor::Inf(_) => FpCategory::Infinite,
1139            Flavor::NaN => FpCategory::Nan,
1140        }
1141    }
1142
1143    /// Returns the remainder of division of `self` by `d1`.
1144    pub fn rem(&self, d1: &Self) -> Self {
1145        self.sub(&(self.div(&d1)).int().mul(&d1))
1146    }
1147}
1148
1149macro_rules! gen_wrapper2 {
1150    // unwrap error, function requires self as argument
1151    ($comment:literal, $fname:ident, $ret:ty, $pos_inf:block, $neg_inf:block, $($arg:ident, $arg_type:ty),*) => {
1152        #[doc=$comment]
1153        pub fn $fname(&self$(,$arg: $arg_type)*) -> $ret {
1154            match self.inner {
1155                Flavor::Value(v) => Self::result_to_ext(v.$fname($($arg,)*), v.is_zero(), true),
1156                Flavor::Inf(s) => if s == DECIMAL_SIGN_POS $pos_inf else $neg_inf,
1157                Flavor::NaN => NAN,
1158            }
1159        }
1160    };
1161}
1162
1163macro_rules! gen_wrapper4 {
1164    // function requires self as argument
1165    ($comment:literal, $fname:ident, $ret:ty, $pos_inf:block, $neg_inf:block, $($arg:ident, $arg_type:ty),*) => {
1166        #[doc=$comment]
1167        pub fn $fname(&self$(,$arg: $arg_type)*) -> $ret {
1168            let inner = match self.inner {
1169                Flavor::Value(v) => Flavor::Value(v.$fname($($arg,)*)),
1170                Flavor::Inf(s) => if s == DECIMAL_SIGN_POS $pos_inf else $neg_inf,
1171                Flavor::NaN => Flavor::NaN,
1172            };
1173            BigFloat {
1174                inner
1175            }
1176        }
1177    };
1178}
1179
1180impl BigFloat {
1181    gen_wrapper4!(
1182        "Returns the absolute value of `self`.",
1183        abs,
1184        Self,
1185        { Flavor::Inf(DECIMAL_SIGN_POS) },
1186        { Flavor::Inf(DECIMAL_SIGN_POS) },
1187    );
1188    gen_wrapper4!(
1189        "Returns the integer part of `self`.",
1190        int,
1191        Self,
1192        { Flavor::NaN },
1193        { Flavor::NaN },
1194    );
1195    gen_wrapper4!(
1196        "Returns the fractional part of `self`.",
1197        frac,
1198        Self,
1199        { Flavor::NaN },
1200        { Flavor::NaN },
1201    );
1202    gen_wrapper2!(
1203        "Returns the smallest integer greater than or equal to `self`.",
1204        ceil,
1205        Self,
1206        { INF_POS },
1207        { INF_NEG },
1208    );
1209    gen_wrapper2!(
1210        "Returns the largest integer less than or equal to `self`.",
1211        floor,
1212        Self,
1213        { INF_POS },
1214        { INF_NEG },
1215    );
1216    gen_wrapper2!("Returns a rounded number with `n` decimal positions in the fractional part of the number using the rounding mode `rm`.", round, Self, {INF_POS}, {INF_NEG}, n, usize, rm, RoundingMode);
1217
1218    gen_wrapper2!(
1219        "Returns the square root of `self`.",
1220        sqrt,
1221        Self,
1222        { INF_POS },
1223        { NAN },
1224    );
1225    gen_wrapper2!(
1226        "Returns the cube root of `self`.",
1227        cbrt,
1228        Self,
1229        { INF_POS },
1230        { INF_NEG },
1231    );
1232    gen_wrapper2!(
1233        "Returns the natural logarithm of `self`.",
1234        ln,
1235        Self,
1236        { INF_POS },
1237        { NAN },
1238    );
1239    gen_wrapper2!(
1240        "Returns the logarithm base 2 of `self`.",
1241        log2,
1242        Self,
1243        { INF_POS },
1244        { NAN },
1245    );
1246    gen_wrapper2!(
1247        "Returns the logarithm base 10 of `self`.",
1248        log10,
1249        Self,
1250        { INF_POS },
1251        { NAN },
1252    );
1253    gen_wrapper2!(
1254        "Returns `e` to the power of `self`.",
1255        exp,
1256        Self,
1257        { INF_POS },
1258        { INF_NEG },
1259    );
1260
1261    gen_wrapper2!(
1262        "Returns the sine of `self`. The function takes an angle in radians as an argument.",
1263        sin,
1264        Self,
1265        { NAN },
1266        { NAN },
1267    );
1268    gen_wrapper2!(
1269        "Returns the cosine of `self`. The function takes an angle in radians as an argument.",
1270        cos,
1271        Self,
1272        { NAN },
1273        { NAN },
1274    );
1275    gen_wrapper2!(
1276        "Returns the tangent of `self`. The function takes an angle in radians as an argument.",
1277        tan,
1278        Self,
1279        { NAN },
1280        { NAN },
1281    );
1282    gen_wrapper2!("Returns the arcsine of `self`. The result is an angle in radians ranging from -pi/2 to pi/2.", asin, Self, {NAN}, {NAN},);
1283    gen_wrapper2!(
1284        "Returns the arccosine of `self`. The result is an angle in radians ranging from 0 to pi.",
1285        acos,
1286        Self,
1287        { NAN },
1288        { NAN },
1289    );
1290    gen_wrapper2!("Returns the arctangent of `self`. The result is an angle in radians ranging from -pi/2 to pi/2.", atan, Self, {HALF_PI}, {HALF_PI.inv_sign()},);
1291
1292    gen_wrapper2!(
1293        "Returns the hyperbolic sine of `self`.",
1294        sinh,
1295        Self,
1296        { INF_POS },
1297        { INF_NEG },
1298    );
1299    gen_wrapper2!(
1300        "Returns the hyperbolic cosine of `self`.",
1301        cosh,
1302        Self,
1303        { INF_POS },
1304        { INF_POS },
1305    );
1306    gen_wrapper2!(
1307        "Returns the hyperbolic tangent of `self`.",
1308        tanh,
1309        Self,
1310        { ONE },
1311        { ONE.inv_sign() },
1312    );
1313    gen_wrapper2!(
1314        "Returns the inverse hyperbolic sine of `self`.",
1315        asinh,
1316        Self,
1317        { INF_POS },
1318        { INF_NEG },
1319    );
1320    gen_wrapper2!(
1321        "Returns the inverse hyperbolic cosine of `self`.",
1322        acosh,
1323        Self,
1324        { ZERO },
1325        { ZERO },
1326    );
1327    gen_wrapper2!(
1328        "Returns the inverse hyperbolic tangent of `self`.",
1329        atanh,
1330        Self,
1331        { ZERO },
1332        { ZERO },
1333    );
1334}
1335
1336/// Standard library features
1337pub mod ops {
1338
1339    use crate::BigFloat;
1340    use crate::NAN;
1341    use crate::ONE;
1342    use crate::ZERO;
1343
1344    #[cfg(feature = "std")]
1345    use std::{
1346        cmp::Eq, cmp::Ordering, cmp::PartialEq, cmp::PartialOrd, fmt::Display, fmt::Formatter,
1347        iter::Product, iter::Sum, ops::Add, ops::AddAssign, ops::Div, ops::DivAssign, ops::Mul,
1348        ops::MulAssign, ops::Neg, ops::Rem, ops::Sub, ops::SubAssign, str::FromStr,
1349    };
1350
1351    #[cfg(not(feature = "std"))]
1352    use core::{
1353        cmp::Eq, cmp::Ordering, cmp::PartialEq, cmp::PartialOrd, fmt::Display, fmt::Formatter,
1354        iter::Product, iter::Sum, ops::Add, ops::AddAssign, ops::Div, ops::DivAssign, ops::Mul,
1355        ops::MulAssign, ops::Neg, ops::Rem, ops::Sub, ops::SubAssign, str::FromStr,
1356    };
1357
1358    //
1359    // ops traits
1360    //
1361
1362    impl Add for BigFloat {
1363        type Output = Self;
1364        fn add(self, rhs: Self) -> Self::Output {
1365            BigFloat::add(&self, &rhs)
1366        }
1367    }
1368
1369    impl AddAssign for BigFloat {
1370        fn add_assign(&mut self, rhs: Self) {
1371            *self = BigFloat::add(self, &rhs)
1372        }
1373    }
1374
1375    impl Div for BigFloat {
1376        type Output = Self;
1377        fn div(self, rhs: Self) -> Self::Output {
1378            BigFloat::div(&self, &rhs)
1379        }
1380    }
1381
1382    impl DivAssign for BigFloat {
1383        fn div_assign(&mut self, rhs: Self) {
1384            *self = BigFloat::div(self, &rhs)
1385        }
1386    }
1387
1388    impl Rem for BigFloat {
1389        type Output = Self;
1390        fn rem(self, rhs: Self) -> Self::Output {
1391            BigFloat::rem(&self, &rhs)
1392        }
1393    }
1394
1395    impl Mul for BigFloat {
1396        type Output = Self;
1397        fn mul(self, rhs: Self) -> Self::Output {
1398            BigFloat::mul(&self, &rhs)
1399        }
1400    }
1401
1402    impl MulAssign for BigFloat {
1403        fn mul_assign(&mut self, rhs: Self) {
1404            *self = BigFloat::mul(self, &rhs)
1405        }
1406    }
1407
1408    impl Neg for BigFloat {
1409        type Output = Self;
1410        fn neg(self) -> Self::Output {
1411            self.inv_sign()
1412        }
1413    }
1414
1415    impl Neg for &BigFloat {
1416        type Output = BigFloat;
1417        fn neg(self) -> Self::Output {
1418            (*self).inv_sign()
1419        }
1420    }
1421
1422    impl Sub for BigFloat {
1423        type Output = Self;
1424        fn sub(self, rhs: Self) -> Self::Output {
1425            BigFloat::sub(&self, &rhs)
1426        }
1427    }
1428
1429    impl SubAssign for BigFloat {
1430        fn sub_assign(&mut self, rhs: Self) {
1431            *self = BigFloat::sub(self, &rhs)
1432        }
1433    }
1434
1435    impl Add<&BigFloat> for BigFloat {
1436        type Output = Self;
1437        fn add(self, rhs: &BigFloat) -> Self::Output {
1438            BigFloat::add(&self, rhs)
1439        }
1440    }
1441
1442    impl AddAssign<&BigFloat> for BigFloat {
1443        fn add_assign(&mut self, rhs: &BigFloat) {
1444            *self = BigFloat::add(self, &rhs)
1445        }
1446    }
1447
1448    impl Div<&BigFloat> for BigFloat {
1449        type Output = Self;
1450        fn div(self, rhs: &BigFloat) -> Self::Output {
1451            BigFloat::div(&self, &rhs)
1452        }
1453    }
1454
1455    impl DivAssign<&BigFloat> for BigFloat {
1456        fn div_assign(&mut self, rhs: &BigFloat) {
1457            *self = BigFloat::div(self, &rhs)
1458        }
1459    }
1460
1461    impl Mul<&BigFloat> for BigFloat {
1462        type Output = Self;
1463        fn mul(self, rhs: &BigFloat) -> Self::Output {
1464            BigFloat::mul(&self, &rhs)
1465        }
1466    }
1467
1468    impl MulAssign<&BigFloat> for BigFloat {
1469        fn mul_assign(&mut self, rhs: &BigFloat) {
1470            *self = BigFloat::mul(self, &rhs)
1471        }
1472    }
1473
1474    impl Sub<&BigFloat> for BigFloat {
1475        type Output = Self;
1476        fn sub(self, rhs: &BigFloat) -> Self::Output {
1477            BigFloat::sub(&self, &rhs)
1478        }
1479    }
1480
1481    impl SubAssign<&BigFloat> for BigFloat {
1482        fn sub_assign(&mut self, rhs: &BigFloat) {
1483            *self = BigFloat::sub(self, &rhs)
1484        }
1485    }
1486
1487    //
1488    // ordering traits
1489    //
1490
1491    impl PartialEq for BigFloat {
1492        fn eq(&self, other: &Self) -> bool {
1493            let cmp_result = BigFloat::cmp(self, other);
1494            matches!(cmp_result, Some(0))
1495        }
1496    }
1497
1498    impl Eq for BigFloat {}
1499
1500    impl PartialOrd for BigFloat {
1501        fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
1502            let cmp_result = BigFloat::cmp(self, other);
1503            match cmp_result {
1504                Some(v) => {
1505                    if v > 0 {
1506                        Some(Ordering::Greater)
1507                    } else if v < 0 {
1508                        Some(Ordering::Less)
1509                    } else {
1510                        Some(Ordering::Equal)
1511                    }
1512                }
1513                None => None,
1514            }
1515        }
1516    }
1517
1518    impl From<f64> for BigFloat {
1519        fn from(f: f64) -> Self {
1520            BigFloat::from_f64(f)
1521        }
1522    }
1523
1524    impl From<f32> for BigFloat {
1525        fn from(f: f32) -> Self {
1526            BigFloat::from_f32(f)
1527        }
1528    }
1529
1530    impl Display for BigFloat {
1531        #[cfg(feature = "std")]
1532        fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
1533            self.write_str(f)
1534        }
1535
1536        #[cfg(not(feature = "std"))]
1537        fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), core::fmt::Error> {
1538            self.write_str(f)
1539        }
1540    }
1541
1542    impl Default for BigFloat {
1543        fn default() -> BigFloat {
1544            BigFloat::new()
1545        }
1546    }
1547
1548    impl FromStr for BigFloat {
1549        type Err = BigFloat;
1550
1551        /// Returns parsed number or NAN in case of error.
1552        fn from_str(src: &str) -> Result<BigFloat, Self::Err> {
1553            BigFloat::parse(src).ok_or(NAN)
1554        }
1555    }
1556
1557    impl Product for BigFloat {
1558        fn product<I: Iterator<Item = BigFloat>>(iter: I) -> Self {
1559            let mut acc = ONE;
1560            for v in iter {
1561                acc *= v;
1562            }
1563            acc
1564        }
1565    }
1566
1567    impl Sum for BigFloat {
1568        fn sum<I: Iterator<Item = BigFloat>>(iter: I) -> Self {
1569            let mut acc = ZERO;
1570            for v in iter {
1571                acc += v;
1572            }
1573            acc
1574        }
1575    }
1576
1577    impl<'a> Product<&'a BigFloat> for BigFloat {
1578        fn product<I: Iterator<Item = &'a BigFloat>>(iter: I) -> Self {
1579            let mut acc = ONE;
1580            for v in iter {
1581                acc *= v;
1582            }
1583            acc
1584        }
1585    }
1586
1587    impl<'a> Sum<&'a BigFloat> for BigFloat {
1588        fn sum<I: Iterator<Item = &'a BigFloat>>(iter: I) -> Self {
1589            let mut acc = ZERO;
1590            for v in iter {
1591                acc += v;
1592            }
1593            acc
1594        }
1595    }
1596}
1597
1598macro_rules! impl_int_conv {
1599    ($s:ty, $u:ty, $from_s:ident, $from_u:ident, $from_int:ident) => {
1600        impl BigFloat {
1601            /// Construct BigFloat from integer value.
1602            pub fn $from_s(i: $s) -> Self {
1603                let sign = if i < 0 { DECIMAL_SIGN_NEG } else { DECIMAL_SIGN_POS };
1604                Self::$from_int(i.unsigned_abs(), sign)
1605            }
1606
1607            /// Construct BigFloat from integer value.
1608            pub fn $from_u(i: $u) -> Self {
1609                Self::$from_int(i, DECIMAL_SIGN_POS)
1610            }
1611
1612            fn $from_int(mut v: $u, sign: i8) -> Self {
1613                let mut d = [0u8; DECIMAL_POSITIONS];
1614                let mut p = DECIMAL_POSITIONS;
1615                while v > 0 {
1616                    p -= 1;
1617                    d[p] = (v % 10) as u8;
1618                    v /= 10;
1619                }
1620                if p < DECIMAL_POSITIONS {
1621                    Self::from_bytes(&d[p..], sign, 0)
1622                } else {
1623                    Self::new()
1624                }
1625            }
1626        }
1627
1628        #[cfg(feature = "std")]
1629        impl From<$s> for BigFloat {
1630            fn from(i: $s) -> Self {
1631                BigFloat::$from_s(i)
1632            }
1633        }
1634
1635        #[cfg(feature = "std")]
1636        impl From<$u> for BigFloat {
1637            fn from(i: $u) -> Self {
1638                BigFloat::$from_u(i)
1639            }
1640        }
1641
1642        #[cfg(not(feature = "std"))]
1643        impl core::convert::From<$s> for BigFloat {
1644            fn from(i: $s) -> Self {
1645                BigFloat::$from_s(i)
1646            }
1647        }
1648
1649        #[cfg(not(feature = "std"))]
1650        impl core::convert::From<$u> for BigFloat {
1651            fn from(i: $u) -> Self {
1652                BigFloat::$from_u(i)
1653            }
1654        }
1655    };
1656}
1657
1658impl_int_conv!(i8, u8, from_i8, from_u8, from_int_u8);
1659impl_int_conv!(i16, u16, from_i16, from_u16, from_int_u16);
1660impl_int_conv!(i32, u32, from_i32, from_u32, from_int_u32);
1661impl_int_conv!(i64, u64, from_i64, from_u64, from_int_u64);
1662impl_int_conv!(i128, u128, from_i128, from_u128, from_int_u128);
1663
1664#[cfg(test)]
1665mod tests {
1666
1667    use super::*;
1668    use crate::defs::{
1669        RoundingMode, DECIMAL_PARTS, I128_MAX, I128_MIN, I64_MAX, I64_MIN, U128_MAX, U64_MAX,
1670    };
1671    use crate::ext::Flavor;
1672
1673    #[cfg(feature = "std")]
1674    use std::str::FromStr;
1675
1676    #[cfg(not(feature = "std"))]
1677    use core::str::FromStr;
1678
1679    #[test]
1680    fn test_ext() {
1681        // Inf & NaN
1682        let d1 = ONE;
1683        assert!(!d1.is_inf());
1684        assert!(!d1.is_nan());
1685        assert!(!d1.is_inf_pos());
1686        assert!(!d1.is_inf_neg());
1687        assert!(d1.get_sign() > 0);
1688
1689        let d1 = ONE.div(&BigFloat::new());
1690        assert!(d1.is_inf());
1691        assert!(!d1.is_nan());
1692        assert!(d1.is_inf_pos());
1693        assert!(!d1.is_inf_neg());
1694        assert!(d1.get_sign() > 0);
1695
1696        let d1 = d1.inv_sign();
1697        assert!(d1.is_inf());
1698        assert!(!d1.is_nan());
1699        assert!(!d1.is_inf_pos());
1700        assert!(d1.is_inf_neg());
1701        assert!(d1.get_sign() < 0);
1702
1703        let d1 = BigFloat::new().div(&BigFloat::new());
1704        assert!(!d1.is_inf());
1705        assert!(d1.is_nan());
1706        assert!(!d1.is_inf_pos());
1707        assert!(!d1.is_inf_neg());
1708        assert!(d1.get_sign() == 0);
1709
1710        // conversions
1711        let d1 = ONE;
1712        assert!(d1.to_f64() == 1.0);
1713        assert!(d1.to_f32() == 1.0);
1714        assert!(d1.to_i64() == Some(1));
1715        assert!(d1.to_u64() == Some(1));
1716        assert!(d1.to_i128() == Some(1));
1717        assert!(d1.to_u128() == Some(1));
1718        let d1 = BigFloat::new().div(&BigFloat::new());
1719        assert!(d1.to_f64().is_nan());
1720        assert!(d1.to_f32().is_nan());
1721        assert!(d1.to_i64().is_none());
1722        assert!(d1.to_u64().is_none());
1723        assert!(d1.to_i128().is_none());
1724        assert!(d1.to_u128().is_none());
1725        let d1 = ONE.div(&BigFloat::new());
1726        assert!(d1.to_f64().is_infinite());
1727        assert!(d1.to_f32().is_infinite());
1728        assert!(d1.to_f64().is_sign_positive());
1729        assert!(d1.to_f32().is_sign_positive());
1730        assert!(d1.to_i64().is_none());
1731        assert!(d1.to_u64().is_none());
1732        assert!(d1.to_i128().is_none());
1733        assert!(d1.to_u128().is_none());
1734        let d1 = d1.inv_sign();
1735        assert!(d1.to_f64().is_sign_negative());
1736        assert!(d1.to_f32().is_sign_negative());
1737        assert!(d1.to_f64().is_infinite());
1738        assert!(d1.to_f32().is_infinite());
1739        assert!(d1.to_i64().is_none());
1740        assert!(d1.to_u64().is_none());
1741        assert!(d1.to_i128().is_none());
1742        assert!(d1.to_u128().is_none());
1743
1744        let d1 = BigFloat {
1745            inner: Flavor::Value(I64_MAX),
1746        };
1747        assert!(d1.to_i64() == Some(i64::MAX));
1748        assert!(d1.add(&ONE).to_i64() == None);
1749        let d1 = BigFloat {
1750            inner: Flavor::Value(I64_MIN),
1751        };
1752        assert!(d1.to_i64() == Some(i64::MIN));
1753        assert!(d1.sub(&ONE).to_i64() == None);
1754        let d1 = BigFloat {
1755            inner: Flavor::Value(U64_MAX),
1756        };
1757        assert!(d1.to_u64() == Some(u64::MAX));
1758        assert!(d1.add(&ONE).to_u64() == None);
1759        let d1 = BigFloat {
1760            inner: Flavor::Value(I128_MAX),
1761        };
1762        assert!(d1.to_i128() == Some(i128::MAX));
1763        assert!(d1.add(&ONE).to_i128() == None);
1764        let d1 = BigFloat {
1765            inner: Flavor::Value(I128_MIN),
1766        };
1767        assert!(d1.to_i128() == Some(i128::MIN));
1768        assert!(d1.sub(&ONE).to_i128() == None);
1769        let d1 = BigFloat {
1770            inner: Flavor::Value(U128_MAX),
1771        };
1772        assert!(d1.to_u128() == Some(u128::MAX));
1773        assert!(d1.add(&ONE).to_u128() == None);
1774
1775        for _ in 0..1000 {
1776            let i = rand::random::<i64>();
1777            let d1 = BigFloat::from_i64(i);
1778            assert!(d1.to_i64() == Some(i));
1779
1780            let i = rand::random::<u64>();
1781            let d1 = BigFloat::from_u64(i);
1782            assert!(d1.to_u64() == Some(i));
1783
1784            let i = rand::random::<i128>();
1785            let d1 = BigFloat::from_i128(i);
1786            assert!(d1.to_i128() == Some(i));
1787
1788            let i = rand::random::<u128>();
1789            let d1 = BigFloat::from_u128(i);
1790            assert!(d1.to_u128() == Some(i));
1791        }
1792
1793        let d1 = ONE;
1794        let mut bytes = [1; DECIMAL_PARTS];
1795        d1.get_mantissa_bytes(&mut bytes);
1796        assert!(bytes != [1; DECIMAL_PARTS]);
1797        assert!(d1.get_mantissa_len() != 0);
1798        let mut bytes = [1; DECIMAL_PARTS];
1799        let d1 = INF_POS;
1800        d1.get_mantissa_bytes(&mut bytes);
1801        assert!(d1.get_mantissa_len() == 0);
1802        assert!(bytes == [1; DECIMAL_PARTS]);
1803        let d1 = INF_NEG;
1804        d1.get_mantissa_bytes(&mut bytes);
1805        assert!(d1.get_mantissa_len() == 0);
1806        assert!(bytes == [1; DECIMAL_PARTS]);
1807        let d1 = NAN;
1808        d1.get_mantissa_bytes(&mut bytes);
1809        assert!(d1.get_mantissa_len() == 0);
1810        assert!(bytes == [1; DECIMAL_PARTS]);
1811
1812        assert!(ONE.get_exponent() < 0);
1813        assert!(INF_POS.get_exponent() == 0);
1814        assert!(INF_NEG.get_exponent() == 0);
1815        assert!(NAN.get_exponent() == 0);
1816
1817        assert!(ONE.to_raw_parts().is_some());
1818        assert!(INF_POS.to_raw_parts().is_none());
1819        assert!(INF_NEG.to_raw_parts().is_none());
1820        assert!(NAN.to_raw_parts().is_none());
1821
1822        assert!(ONE.add(&ONE).cmp(&TWO) == Some(0));
1823        assert!(ONE.add(&INF_POS).is_inf_pos());
1824        assert!(INF_POS.add(&ONE).is_inf_pos());
1825        assert!(ONE.add(&INF_NEG).is_inf_neg());
1826        assert!(INF_NEG.add(&ONE).is_inf_neg());
1827        assert!(INF_POS.add(&INF_POS).is_inf_pos());
1828        assert!(INF_POS.add(&INF_NEG).is_nan());
1829        assert!(INF_NEG.add(&INF_NEG).is_inf_neg());
1830        assert!(INF_NEG.add(&INF_POS).is_nan());
1831
1832        assert!(TWO.sub(&ONE).cmp(&ONE) == Some(0));
1833        assert!(ONE.sub(&INF_POS).is_inf_neg());
1834        assert!(INF_POS.sub(&ONE).is_inf_pos());
1835        assert!(ONE.sub(&INF_NEG).is_inf_pos());
1836        assert!(INF_NEG.sub(&ONE).is_inf_neg());
1837        assert!(INF_POS.sub(&INF_POS).is_nan());
1838        assert!(INF_POS.sub(&INF_NEG).is_inf_pos());
1839        assert!(INF_NEG.sub(&INF_NEG).is_nan());
1840        assert!(INF_NEG.sub(&INF_POS).is_inf_neg());
1841
1842        assert!(TWO.mul(&ONE).cmp(&TWO) == Some(0));
1843        assert!(ONE.mul(&INF_POS).is_inf_pos());
1844        assert!(INF_POS.mul(&ONE).is_inf_pos());
1845        assert!(ONE.mul(&INF_NEG).is_inf_neg());
1846        assert!(INF_NEG.mul(&ONE).is_inf_neg());
1847        assert!(ONE.inv_sign().mul(&INF_POS).is_inf_neg());
1848        assert!(ONE.inv_sign().mul(&INF_NEG).is_inf_pos());
1849        assert!(INF_POS.mul(&ONE.inv_sign()).is_inf_neg());
1850        assert!(INF_NEG.mul(&ONE.inv_sign()).is_inf_pos());
1851        assert!(INF_POS.mul(&INF_POS).is_inf_pos());
1852        assert!(INF_POS.mul(&INF_NEG).is_inf_neg());
1853        assert!(INF_NEG.mul(&INF_NEG).is_inf_pos());
1854        assert!(INF_NEG.mul(&INF_POS).is_inf_neg());
1855        assert!(INF_POS.mul(&BigFloat::new()).is_nan());
1856        assert!(INF_NEG.mul(&BigFloat::new()).is_nan());
1857        assert!(BigFloat::new().mul(&INF_POS).is_nan());
1858        assert!(BigFloat::new().mul(&INF_NEG).is_nan());
1859
1860        assert!(TWO.div(&TWO).cmp(&ONE) == Some(0));
1861        assert!(TWO.div(&INF_POS).is_zero());
1862        assert!(INF_POS.div(&TWO).is_inf_pos());
1863        assert!(TWO.div(&INF_NEG).is_zero());
1864        assert!(INF_NEG.div(&TWO).is_inf_neg());
1865        assert!(TWO.inv_sign().div(&INF_POS).is_zero());
1866        assert!(TWO.inv_sign().div(&INF_NEG).is_zero());
1867        assert!(INF_POS.div(&TWO.inv_sign()).is_inf_neg());
1868        assert!(INF_NEG.div(&TWO.inv_sign()).is_inf_pos());
1869        assert!(INF_POS.div(&INF_POS).is_nan());
1870        assert!(INF_POS.div(&INF_NEG).is_nan());
1871        assert!(INF_NEG.div(&INF_NEG).is_nan());
1872        assert!(INF_NEG.div(&INF_POS).is_nan());
1873        assert!(INF_POS.div(&BigFloat::new()).is_inf_pos());
1874        assert!(INF_NEG.div(&BigFloat::new()).is_inf_neg());
1875        assert!(BigFloat::new().div(&INF_POS).is_zero());
1876        assert!(BigFloat::new().div(&INF_NEG).is_zero());
1877
1878        for op in [BigFloat::add, BigFloat::sub, BigFloat::mul, BigFloat::div] {
1879            assert!(op(&NAN, &ONE).is_nan());
1880            assert!(op(&ONE, &NAN).is_nan());
1881            assert!(op(&NAN, &INF_POS).is_nan());
1882            assert!(op(&INF_POS, &NAN).is_nan());
1883            assert!(op(&NAN, &INF_NEG).is_nan());
1884            assert!(op(&INF_NEG, &NAN).is_nan());
1885            assert!(op(&NAN, &NAN).is_nan());
1886        }
1887
1888        assert!(ONE.cmp(&ONE).unwrap() == 0);
1889        assert!(ONE.cmp(&INF_POS).unwrap() < 0);
1890        assert!(INF_POS.cmp(&ONE).unwrap() > 0);
1891        assert!(INF_POS.cmp(&INF_POS).unwrap() == 0);
1892        assert!(ONE.cmp(&INF_NEG).unwrap() > 0);
1893        assert!(INF_NEG.cmp(&ONE).unwrap() < 0);
1894        assert!(INF_NEG.cmp(&INF_NEG).unwrap() == 0);
1895        assert!(ONE.cmp(&NAN).is_none());
1896        assert!(NAN.cmp(&ONE).is_none());
1897        assert!(INF_POS.cmp(&NAN).is_none());
1898        assert!(NAN.cmp(&INF_POS).is_none());
1899        assert!(INF_NEG.cmp(&NAN).is_none());
1900        assert!(NAN.cmp(&INF_NEG).is_none());
1901        assert!(NAN.cmp(&NAN).is_none());
1902
1903        assert!(ONE.is_positive());
1904        assert!(!ONE.is_negative());
1905
1906        assert!(ONE.inv_sign().is_negative());
1907        assert!(!ONE.inv_sign().is_positive());
1908        assert!(!INF_POS.is_negative());
1909        assert!(INF_POS.is_positive());
1910        assert!(INF_NEG.is_negative());
1911        assert!(!INF_NEG.is_positive());
1912        assert!(!NAN.is_positive());
1913        assert!(!NAN.is_negative());
1914
1915        assert!(ONE.pow(&ONE).cmp(&ONE) == Some(0));
1916        assert!(BigFloat::new().pow(&INF_POS).is_zero());
1917        assert!(BigFloat::new().pow(&INF_NEG).is_zero());
1918        assert!(ONE.pow(&INF_POS).cmp(&ONE) == Some(0));
1919        assert!(ONE.pow(&INF_NEG).cmp(&ONE) == Some(0));
1920        assert!(TWO.pow(&INF_POS).is_inf_pos());
1921        assert!(TWO.pow(&INF_NEG).is_inf_neg());
1922        assert!(INF_POS.pow(&ONE).is_inf_pos());
1923        assert!(INF_NEG.pow(&ONE).is_inf_neg());
1924        assert!(INF_NEG.pow(&TWO).is_inf_pos());
1925        assert!(INF_NEG.pow(&BigFloat::from_f64(10.2)).is_inf_pos());
1926        assert!(INF_NEG.pow(&BigFloat::from_f64(3.0)).is_inf_neg());
1927        assert!(INF_POS.pow(&ONE.inv_sign()).is_zero());
1928        assert!(INF_NEG.pow(&ONE.inv_sign()).is_zero());
1929        assert!(INF_POS.pow(&BigFloat::new()).cmp(&ONE) == Some(0));
1930        assert!(INF_NEG.pow(&BigFloat::new()).cmp(&ONE) == Some(0));
1931        assert!(INF_POS.pow(&INF_POS).is_inf_pos());
1932        assert!(INF_NEG.pow(&INF_POS).is_inf_pos());
1933        assert!(INF_POS.pow(&INF_NEG).is_zero());
1934        assert!(INF_NEG.pow(&INF_NEG).is_zero());
1935
1936        let half = ONE.div(&TWO);
1937        assert!(TWO.log(&TWO).cmp(&ONE) == Some(0));
1938        assert!(TWO.log(&INF_POS).is_zero());
1939        assert!(TWO.log(&INF_NEG).is_nan());
1940        assert!(INF_POS.log(&TWO).is_inf_pos());
1941        assert!(INF_NEG.log(&TWO).is_nan());
1942        assert!(half.log(&half).cmp(&ONE) == Some(0));
1943        assert!(half.log(&INF_POS).is_zero());
1944        assert!(half.log(&INF_NEG).is_nan());
1945        assert!(INF_POS.log(&half).is_inf_neg());
1946        assert!(INF_NEG.log(&half).is_nan());
1947        assert!(INF_POS.log(&INF_POS).is_nan());
1948        assert!(INF_POS.log(&INF_NEG).is_nan());
1949        assert!(INF_NEG.log(&INF_POS).is_nan());
1950        assert!(INF_NEG.log(&INF_NEG).is_nan());
1951        assert!(TWO.log(&ONE).is_inf_pos());
1952        assert!(half.log(&ONE).is_inf_pos());
1953        assert!(ONE.log(&ONE).is_nan());
1954
1955        assert!(BigFloat::from_f32(f32::NAN).is_nan());
1956        assert!(BigFloat::from_f32(f32::INFINITY).is_inf_pos());
1957        assert!(BigFloat::from_f32(f32::NEG_INFINITY).is_inf_neg());
1958        assert!(!BigFloat::from_f32(1.0).is_nan());
1959        assert!(BigFloat::from_f64(f64::NAN).is_nan());
1960        assert!(BigFloat::from_f64(f64::INFINITY).is_inf_pos());
1961        assert!(BigFloat::from_f64(f64::NEG_INFINITY).is_inf_neg());
1962        assert!(!BigFloat::from_f64(1.0).is_nan());
1963
1964        assert!(ONE.pow(&NAN).is_nan());
1965        assert!(NAN.pow(&ONE).is_nan());
1966        assert!(INF_POS.pow(&NAN).is_nan());
1967        assert!(NAN.pow(&INF_POS).is_nan());
1968        assert!(INF_NEG.pow(&NAN).is_nan());
1969        assert!(NAN.pow(&INF_NEG).is_nan());
1970        assert!(NAN.pow(&NAN).is_nan());
1971
1972        assert!(TWO.log(&NAN).is_nan());
1973        assert!(NAN.log(&TWO).is_nan());
1974        assert!(INF_POS.log(&NAN).is_nan());
1975        assert!(NAN.log(&INF_POS).is_nan());
1976        assert!(INF_NEG.log(&NAN).is_nan());
1977        assert!(NAN.log(&INF_NEG).is_nan());
1978        assert!(NAN.log(&NAN).is_nan());
1979
1980        assert!(INF_NEG.abs().is_inf_pos());
1981        assert!(INF_POS.abs().is_inf_pos());
1982        assert!(NAN.abs().is_nan());
1983
1984        assert!(INF_NEG.int().is_nan());
1985        assert!(INF_POS.int().is_nan());
1986        assert!(NAN.int().is_nan());
1987
1988        assert!(INF_NEG.frac().is_nan());
1989        assert!(INF_POS.frac().is_nan());
1990        assert!(NAN.frac().is_nan());
1991
1992        assert!(INF_NEG.ceil().is_inf_neg());
1993        assert!(INF_POS.ceil().is_inf_pos());
1994        assert!(NAN.ceil().is_nan());
1995
1996        assert!(INF_NEG.floor().is_inf_neg());
1997        assert!(INF_POS.floor().is_inf_pos());
1998        assert!(NAN.floor().is_nan());
1999
2000        for rm in [
2001            RoundingMode::Up,
2002            RoundingMode::Down,
2003            RoundingMode::ToZero,
2004            RoundingMode::FromZero,
2005            RoundingMode::ToEven,
2006            RoundingMode::ToOdd,
2007        ] {
2008            assert!(INF_NEG.round(0, rm).is_inf_neg());
2009            assert!(INF_POS.round(0, rm).is_inf_pos());
2010            assert!(NAN.round(0, rm).is_nan());
2011        }
2012
2013        assert!(INF_NEG.sqrt().is_nan());
2014        assert!(INF_POS.sqrt().is_inf_pos());
2015        assert!(NAN.sqrt().is_nan());
2016
2017        assert!(INF_NEG.cbrt().is_inf_neg());
2018        assert!(INF_POS.cbrt().is_inf_pos());
2019        assert!(NAN.cbrt().is_nan());
2020
2021        for op in [BigFloat::ln, BigFloat::log2, BigFloat::log10] {
2022            assert!(op(&INF_NEG).is_nan());
2023            assert!(op(&INF_POS).is_inf_pos());
2024            assert!(op(&NAN).is_nan());
2025        }
2026
2027        assert!(INF_NEG.exp().is_inf_neg());
2028        assert!(INF_POS.exp().is_inf_pos());
2029        assert!(NAN.exp().is_nan());
2030
2031        assert!(INF_NEG.sin().is_nan());
2032        assert!(INF_POS.sin().is_nan());
2033        assert!(NAN.sin().is_nan());
2034
2035        assert!(INF_NEG.cos().is_nan());
2036        assert!(INF_POS.cos().is_nan());
2037        assert!(NAN.cos().is_nan());
2038
2039        assert!(INF_NEG.tan().is_nan());
2040        assert!(INF_POS.tan().is_nan());
2041        assert!(NAN.tan().is_nan());
2042
2043        assert!(INF_NEG.asin().is_nan());
2044        assert!(INF_POS.asin().is_nan());
2045        assert!(NAN.asin().is_nan());
2046
2047        assert!(INF_NEG.acos().is_nan());
2048        assert!(INF_POS.acos().is_nan());
2049        assert!(NAN.acos().is_nan());
2050
2051        assert!(INF_NEG.atan().cmp(&HALF_PI.inv_sign()) == Some(0));
2052        assert!(INF_POS.atan().cmp(&HALF_PI) == Some(0));
2053        assert!(NAN.atan().is_nan());
2054        assert!((-ONE).atan().is_negative());
2055        assert!(ONE.atan().is_positive());
2056
2057        assert!(INF_NEG.sinh().is_inf_neg());
2058        assert!(INF_POS.sinh().is_inf_pos());
2059        assert!(NAN.sinh().is_nan());
2060
2061        assert!(INF_NEG.cosh().is_inf_pos());
2062        assert!(INF_POS.cosh().is_inf_pos());
2063        assert!(NAN.cosh().is_nan());
2064
2065        assert!(INF_NEG.tanh().cmp(&ONE.inv_sign()) == Some(0));
2066        assert!(INF_POS.tanh().cmp(&ONE) == Some(0));
2067        assert!(NAN.tanh().is_nan());
2068
2069        assert!(INF_NEG.asinh().is_inf_neg());
2070        assert!(INF_POS.asinh().is_inf_pos());
2071        assert!(NAN.asinh().is_nan());
2072
2073        assert!(INF_NEG.acosh().is_zero());
2074        assert!(INF_POS.acosh().is_zero());
2075        assert!(NAN.acosh().is_nan());
2076
2077        assert!(INF_NEG.atanh().is_zero());
2078        assert!(INF_POS.atanh().is_zero());
2079        assert!(NAN.atanh().is_nan());
2080    }
2081
2082    #[test]
2083    pub fn test_ops() {
2084        let d1 = ONE;
2085        let d2 = BigFloat::new();
2086        assert!(d1 - d2 == d1);
2087        assert!(d1 + d2 == d1);
2088        let mut d3 = BigFloat::new();
2089        d3 += d1;
2090        assert!(d1 == d3);
2091        d3 -= d1;
2092        assert!(d1 > d3);
2093        d3 = TWO;
2094        d3 *= TWO;
2095        assert!(d3 == TWO * TWO);
2096        d3 /= TWO;
2097        assert!(TWO == d3);
2098        assert!(ONE < d3);
2099        assert!(ONE == TWO / TWO);
2100
2101        let d1 = -TWO;
2102        assert!(d1.is_negative());
2103
2104        let d1 = ONE;
2105        let d2 = BigFloat::new();
2106        assert!(d1 - &d2 == d1);
2107        assert!(d1 + &d2 == d1);
2108        let mut d3 = BigFloat::new();
2109        d3 += &d1;
2110        assert!(d1 == d3);
2111        d3 -= &d1;
2112        assert!(d1 > d3);
2113        d3 = TWO;
2114        d3 *= &TWO;
2115        assert!(d3 == TWO * &TWO);
2116        d3 /= &TWO;
2117        assert!(TWO == d3);
2118        assert!(ONE < d3);
2119        assert!(ONE == TWO / &TWO);
2120
2121        let d1 = -&TWO;
2122        assert!(d1.is_negative());
2123
2124        let d1 = BigFloat::from_f64(0.0123456789);
2125
2126        let mut buf = [0u8; 256];
2127        let wblen = fmt_to_str(&d1, &mut buf).len();
2128        let d1str = core::str::from_utf8(&buf[..wblen]).unwrap();
2129        assert_eq!(d1str, "1.234567890000000000000000000000000000000e-2");
2130        assert!(BigFloat::from_str(d1str).unwrap() == d1);
2131
2132        let d1 = BigFloat::from_f64(-123.456789);
2133        let wblen = fmt_to_str(&d1, &mut buf).len();
2134        let d1str = core::str::from_utf8(&buf[..wblen]).unwrap();
2135        assert!(d1str == "-1.234567890000000000000000000000000000000e+2");
2136        assert!(BigFloat::from_str(d1str).unwrap() == d1);
2137
2138        let wblen = fmt_to_str(&INF_POS, &mut buf).len();
2139        let d1str = core::str::from_utf8(&buf[..wblen]).unwrap();
2140        assert!(d1str == "Inf");
2141
2142        let wblen = fmt_to_str(&INF_NEG, &mut buf).len();
2143        let d1str = core::str::from_utf8(&buf[..wblen]).unwrap();
2144        assert!(d1str == "-Inf");
2145
2146        let wblen = fmt_to_str(&NAN, &mut buf).len();
2147        let d1str = core::str::from_utf8(&buf[..wblen]).unwrap();
2148        assert!(d1str == "NaN");
2149
2150        assert!(BigFloat::from_str("abc").unwrap_err().is_nan());
2151
2152        let arr = [TWO, ONE, TWO];
2153        assert!(arr.into_iter().product::<BigFloat>() == TWO * TWO);
2154        assert!(arr.into_iter().sum::<BigFloat>() == TWO + ONE + TWO);
2155
2156        assert!(BigFloat::from_i8(-123) == BigFloat::parse("-1.23e+2").unwrap());
2157        assert!(BigFloat::from_u8(123) == BigFloat::parse("1.23e+2").unwrap());
2158        assert!(BigFloat::from_i16(-12312) == BigFloat::parse("-1.2312e+4").unwrap());
2159        assert!(BigFloat::from_u16(12312) == BigFloat::parse("1.2312e+4").unwrap());
2160        assert!(BigFloat::from_i32(-123456789) == BigFloat::parse("-1.23456789e+8").unwrap());
2161        assert!(BigFloat::from_u32(123456789) == BigFloat::parse("1.23456789e+8").unwrap());
2162        assert!(
2163            BigFloat::from_i64(-1234567890123456789)
2164                == BigFloat::parse("-1.234567890123456789e+18").unwrap()
2165        );
2166        assert!(
2167            BigFloat::from_u64(1234567890123456789)
2168                == BigFloat::parse("1.234567890123456789e+18").unwrap()
2169        );
2170        assert!(
2171            BigFloat::from_i128(-123456789012345678901234567890123456789)
2172                == BigFloat::parse("-1.23456789012345678901234567890123456789e+38").unwrap()
2173        );
2174        assert!(
2175            BigFloat::from_u128(123456789012345678901234567890123456789)
2176                == BigFloat::parse("1.23456789012345678901234567890123456789e+38").unwrap()
2177        );
2178        // Regression Tests: If the number of leading zeros were equal to the number of remaining
2179        // digits in the integral part, `parse` would always yield an exponent of 39.
2180        assert!(ONE == BigFloat::parse("01").unwrap());
2181        assert!(BigFloat::from_u32(987654321) == BigFloat::parse("000000000987654321.0").unwrap());
2182        assert!(BigFloat::parse("9.9e-1") == BigFloat::parse("0099e-2"));
2183    }
2184
2185    fn fmt_to_str<'a>(f: &BigFloat, buf: &'a mut [u8]) -> WritableBuf<'a> {
2186        buf.fill(0);
2187        let mut strepr = WritableBuf::new(buf);
2188        write!(strepr, "{}", f).unwrap();
2189        strepr
2190    }
2191}
2192
2193#[cfg(feature = "serde")]
2194#[cfg(test)]
2195mod serde_tests {
2196
2197    use super::*;
2198
2199    #[test]
2200    fn test_serde() {
2201        let d1 = E;
2202
2203        let json = serde_json::to_string(&d1).unwrap();
2204
2205        assert_eq!("{\"inner\":{\"Value\":{\"sign\":1,\"e\":-39,\"n\":40,\"m\":[7757,6249,3526,7471,6028,2353,9045,2845,2818,2718]}}}", json);
2206
2207        let json = "{
2208            \"inner\": {
2209                \"Value\": {
2210                    \"sign\": -1,
2211                    \"e\": -39,
2212                    \"n\": 40,
2213                    \"m\": [7757, 6249, 3526, 7471, 6028, 2353, 9045, 2845, 2818, 2718]
2214                }
2215            }
2216        }";
2217
2218        let d1 = d1.inv_sign();
2219        let d2: BigFloat = serde_json::from_str(json).unwrap();
2220
2221        assert!(d1.cmp(&d2).unwrap() == 0);
2222    }
2223}
2224
2225#[cfg(feature = "rand")]
2226#[cfg(test)]
2227mod rand_tests {
2228
2229    use super::*;
2230
2231    #[test]
2232    fn test_rand() {
2233        for _ in 0..1000 {
2234            let exp_from = rand::random::<i8>();
2235            let exp_shift = if DECIMAL_MAX_EXPONENT > exp_from {
2236                rand::random::<u8>() % (DECIMAL_MAX_EXPONENT as i16 - exp_from as i16) as u8
2237            } else {
2238                0
2239            };
2240            let exp_to = (exp_from as i16 + exp_shift as i16) as i8;
2241
2242            let n = BigFloat::random_normal(exp_from, exp_to).unwrap();
2243
2244            assert!(!n.is_subnormal());
2245            assert!(n.get_exponent() >= exp_from && n.get_exponent() <= exp_to);
2246        }
2247    }
2248
2249    #[test]
2250    fn test_consts() {
2251        assert!(ONE + ONE == TWO);
2252        assert!(ONE - ONE == ZERO);
2253        assert!(ONE * ONE == ONE);
2254        assert!(ONE / ONE == ONE);
2255
2256        let mut next_to_one = ONE;
2257        let e = next_to_one.get_exponent();
2258
2259        next_to_one.set_exponent(e + DECIMAL_POSITIONS as i8 - 1);
2260        next_to_one += ONE;
2261        next_to_one.set_exponent(e);
2262        assert!(next_to_one - ONE == EPSILON);
2263
2264        assert!((E.ln() - ONE).abs() <= EPSILON);
2265
2266        let ten = BigFloat::from_u8(10);
2267
2268        assert!((TWO.pow(&LOG2_E) - E).abs() <= EPSILON);
2269        assert!((ten.pow(&LOG10_E) - E).abs() <= EPSILON);
2270
2271        assert!((LN_10 - ten.ln()).abs() <= EPSILON);
2272        assert!((LN_2 - TWO.ln()).abs() <= EPSILON);
2273
2274        assert!((HALF_PI * TWO - PI).abs() <= EPSILON);
2275        assert!((SQRT_2 * SQRT_2 - TWO).abs() <= EPSILON);
2276
2277        assert!((FRAC_1_PI * PI - ONE).abs() <= EPSILON);
2278        assert!((FRAC_1_SQRT_2 * SQRT_2 - ONE).abs() <= EPSILON);
2279        assert!((FRAC_2_PI * PI / TWO - ONE).abs() <= EPSILON);
2280        assert!(
2281            (FRAC_2_SQRT_PI * FRAC_2_SQRT_PI / BigFloat::from_u8(4) * PI - ONE).abs() <= EPSILON
2282        );
2283        assert!((FRAC_PI_3 / PI * BigFloat::from_u8(3) - ONE).abs() <= EPSILON);
2284        assert!((FRAC_PI_4 / PI * BigFloat::from_u8(4) - ONE).abs() <= EPSILON);
2285        assert!((FRAC_PI_6 / PI * BigFloat::from_u8(6) - ONE).abs() <= EPSILON);
2286        assert!((FRAC_PI_8 / PI * BigFloat::from_u8(8) - ONE).abs() <= EPSILON);
2287    }
2288}