num_bigfloat/
num_traits.rs

1//! `num-traits` implementation.
2
3#[cfg(not(feature = "std"))]
4use crate::ext::RAD_TO_DEG_FACTOR;
5use crate::BigFloat;
6use crate::Error;
7#[cfg(feature = "std")]
8use crate::RoundingMode;
9#[cfg(not(feature = "std"))]
10use crate::EPSILON;
11use crate::INF_NEG;
12use crate::INF_POS;
13use crate::MAX;
14use crate::MIN;
15use crate::MIN_POSITIVE_NORMAL;
16use crate::NAN;
17use crate::ONE;
18#[cfg(feature = "std")]
19use crate::PI;
20#[cfg(feature = "std")]
21use crate::TWO;
22use crate::ZERO;
23use core::num::FpCategory;
24use num_traits::bounds::Bounded;
25use num_traits::cast::FromPrimitive;
26use num_traits::cast::NumCast;
27use num_traits::cast::ToPrimitive;
28#[cfg(feature = "std")]
29use num_traits::float::Float;
30use num_traits::float::FloatConst;
31#[cfg(not(feature = "std"))]
32use num_traits::float::FloatCore;
33use num_traits::identities::One;
34use num_traits::identities::Zero;
35use num_traits::ops::euclid::Euclid;
36use num_traits::ops::inv::Inv;
37use num_traits::ops::mul_add::MulAdd;
38use num_traits::ops::mul_add::MulAddAssign;
39use num_traits::pow::Pow;
40use num_traits::sign::Signed;
41use num_traits::Num;
42
43impl Bounded for BigFloat {
44    fn min_value() -> Self {
45        MIN
46    }
47
48    fn max_value() -> Self {
49        MAX
50    }
51}
52
53impl Zero for BigFloat {
54    fn zero() -> Self {
55        ZERO
56    }
57
58    fn is_zero(&self) -> bool {
59        self.is_zero()
60    }
61}
62
63impl One for BigFloat {
64    fn one() -> Self {
65        ONE
66    }
67}
68
69impl Num for BigFloat {
70    type FromStrRadixErr = Error;
71
72    fn from_str_radix(str: &str, radix: u32) -> Result<Self, Self::FromStrRadixErr> {
73        if radix != 10 {
74            return Err(Error::InvalidArgument);
75        }
76
77        BigFloat::parse(str).ok_or(Error::InvalidArgument)
78    }
79}
80
81impl ToPrimitive for BigFloat {
82    fn to_i64(&self) -> Option<i64> {
83        BigFloat::to_i64(self)
84    }
85
86    fn to_u64(&self) -> Option<u64> {
87        BigFloat::to_u64(self)
88    }
89
90    fn to_i128(&self) -> Option<i128> {
91        BigFloat::to_i128(self)
92    }
93
94    fn to_u128(&self) -> Option<u128> {
95        BigFloat::to_u128(self)
96    }
97
98    fn to_f64(&self) -> Option<f64> {
99        Some(BigFloat::to_f64(self))
100    }
101}
102
103impl NumCast for BigFloat {
104    fn from<T: ToPrimitive>(n: T) -> Option<BigFloat> {
105        n.to_f64().map(BigFloat::from_f64)
106    }
107}
108
109#[cfg(feature = "std")]
110impl Float for BigFloat {
111    fn nan() -> Self {
112        NAN
113    }
114
115    fn infinity() -> Self {
116        INF_POS
117    }
118
119    fn neg_infinity() -> Self {
120        INF_NEG
121    }
122
123    /// This function is provided only for compatibility since `-0.0` is not implemented.
124    fn neg_zero() -> Self {
125        ZERO
126    }
127
128    fn min_value() -> Self {
129        MIN
130    }
131
132    fn min_positive_value() -> Self {
133        MIN_POSITIVE_NORMAL
134    }
135
136    fn max_value() -> Self {
137        MAX
138    }
139
140    fn is_nan(self) -> bool {
141        BigFloat::is_nan(&self)
142    }
143
144    fn is_infinite(self) -> bool {
145        BigFloat::is_inf(&self)
146    }
147
148    fn is_finite(self) -> bool {
149        !(BigFloat::is_inf(&self) || BigFloat::is_nan(&self))
150    }
151
152    fn is_normal(self) -> bool {
153        !(self.is_subnormal() || self.is_inf() || self.is_nan() || self.is_zero())
154    }
155
156    fn classify(self) -> FpCategory {
157        BigFloat::classify(&self)
158    }
159
160    fn floor(self) -> Self {
161        BigFloat::floor(&self)
162    }
163
164    fn ceil(self) -> Self {
165        BigFloat::ceil(&self)
166    }
167
168    fn round(self) -> Self {
169        BigFloat::round(&self, 0, RoundingMode::FromZero)
170    }
171
172    fn trunc(self) -> Self {
173        self.int()
174    }
175
176    fn fract(self) -> Self {
177        self.frac()
178    }
179
180    fn abs(self) -> Self {
181        BigFloat::abs(&self)
182    }
183
184    fn signum(self) -> Self {
185        let ret = BigFloat::signum(&self);
186        if ret.is_zero() {
187            ONE
188        } else {
189            ret
190        }
191    }
192
193    /// Note: BigFloat NaN has no sign.
194    fn is_sign_positive(self) -> bool {
195        BigFloat::is_positive(&self)
196    }
197
198    /// Note: BigFloat NaN has no sign.
199    fn is_sign_negative(self) -> bool {
200        BigFloat::is_negative(&self)
201    }
202
203    /// This function is provided only for compatibility. It is not faster than separate multiplication and addition.
204    fn mul_add(self, a: Self, b: Self) -> Self {
205        self * a + b
206    }
207
208    fn recip(self) -> Self {
209        ONE / self
210    }
211
212    /// This function is provided only for compatibility. It is not faster than `powf`.
213    fn powi(self, n: i32) -> Self {
214        let p = BigFloat::from_i32(n);
215        BigFloat::pow(&self, &p)
216    }
217
218    fn powf(self, n: Self) -> Self {
219        BigFloat::pow(&self, &n)
220    }
221
222    fn sqrt(self) -> Self {
223        BigFloat::sqrt(&self)
224    }
225
226    fn exp(self) -> Self {
227        BigFloat::exp(&self)
228    }
229
230    fn exp2(self) -> Self {
231        BigFloat::pow(&TWO, &self)
232    }
233
234    fn ln(self) -> Self {
235        BigFloat::ln(&self)
236    }
237
238    fn log(self, base: Self) -> Self {
239        BigFloat::log(&self, &base)
240    }
241
242    fn log2(self) -> Self {
243        BigFloat::log2(&self)
244    }
245
246    fn log10(self) -> Self {
247        BigFloat::log10(&self)
248    }
249
250    fn max(self, other: Self) -> Self {
251        BigFloat::max(&self, &other)
252    }
253
254    fn min(self, other: Self) -> Self {
255        BigFloat::min(&self, &other)
256    }
257
258    fn abs_sub(self, other: Self) -> Self {
259        let ret = self.sub(&other);
260        if ret.is_negative() {
261            ZERO
262        } else {
263            ret
264        }
265    }
266
267    fn cbrt(self) -> Self {
268        BigFloat::cbrt(&self)
269    }
270
271    fn hypot(self, other: Self) -> Self {
272        (self * self + other * other).sqrt()
273    }
274
275    fn sin(self) -> Self {
276        BigFloat::sin(&self)
277    }
278
279    fn cos(self) -> Self {
280        BigFloat::cos(&self)
281    }
282
283    fn tan(self) -> Self {
284        BigFloat::tan(&self)
285    }
286
287    fn asin(self) -> Self {
288        BigFloat::asin(&self)
289    }
290
291    fn acos(self) -> Self {
292        BigFloat::acos(&self)
293    }
294
295    fn atan(self) -> Self {
296        BigFloat::atan(&self)
297    }
298
299    fn atan2(self, other: Self) -> Self {
300        if self.is_zero() && other.is_zero() {
301            ZERO
302        } else if other.is_negative() {
303            if self.is_negative() {
304                BigFloat::atan(&self.div(&other)) - PI
305            } else {
306                BigFloat::atan(&self.div(&other)) + PI
307            }
308        } else {
309            BigFloat::atan(&self.div(&other))
310        }
311    }
312
313    /// This function is provided only for compatibility.
314    fn sin_cos(self) -> (Self, Self) {
315        (BigFloat::sin(&self), BigFloat::cos(&self))
316    }
317
318    /// This function is provided only for compatibility.
319    fn exp_m1(self) -> Self {
320        self.exp().sub(&ONE)
321    }
322
323    /// This function is provided only for compatibility.
324    fn ln_1p(self) -> Self {
325        self.add(&ONE).ln()
326    }
327
328    fn sinh(self) -> Self {
329        BigFloat::sinh(&self)
330    }
331
332    fn cosh(self) -> Self {
333        BigFloat::cosh(&self)
334    }
335
336    fn tanh(self) -> Self {
337        BigFloat::tanh(&self)
338    }
339
340    fn asinh(self) -> Self {
341        BigFloat::asinh(&self)
342    }
343
344    fn acosh(self) -> Self {
345        BigFloat::acosh(&self)
346    }
347
348    fn atanh(self) -> Self {
349        BigFloat::atanh(&self)
350    }
351
352    /// This function converts BigFloat to f64 and decomposes it.
353    fn integer_decode(self) -> (u64, i16, i8) {
354        let f = self.to_f64();
355
356        let bits: u64 = f.to_bits();
357
358        let sign: i8 = if bits >> 63 == 0 { 1 } else { -1 };
359
360        let mut exponent: i16 = ((bits >> 52) & 0x7ff) as i16;
361
362        let mantissa = if exponent == 0 {
363            (bits & 0xfffffffffffff) << 1
364        } else {
365            (bits & 0xfffffffffffff) | 0x10000000000000
366        };
367
368        exponent -= 1023 + 52;
369
370        (mantissa, exponent, sign)
371    }
372}
373
374impl FloatConst for BigFloat {
375    fn E() -> Self {
376        crate::E
377    }
378
379    fn FRAC_1_PI() -> Self {
380        crate::FRAC_1_PI
381    }
382
383    fn FRAC_1_SQRT_2() -> Self {
384        crate::FRAC_1_SQRT_2
385    }
386
387    fn FRAC_2_PI() -> Self {
388        crate::FRAC_2_PI
389    }
390
391    fn FRAC_2_SQRT_PI() -> Self {
392        crate::FRAC_2_SQRT_PI
393    }
394
395    fn FRAC_PI_2() -> Self {
396        crate::HALF_PI
397    }
398
399    fn FRAC_PI_3() -> Self {
400        crate::FRAC_PI_3
401    }
402
403    fn FRAC_PI_4() -> Self {
404        crate::FRAC_PI_4
405    }
406
407    fn FRAC_PI_6() -> Self {
408        crate::FRAC_PI_6
409    }
410
411    fn FRAC_PI_8() -> Self {
412        crate::FRAC_PI_8
413    }
414
415    fn LN_10() -> Self {
416        crate::LN_10
417    }
418
419    fn LN_2() -> Self {
420        crate::LN_2
421    }
422
423    fn LOG10_E() -> Self {
424        crate::LOG10_E
425    }
426
427    fn LOG2_E() -> Self {
428        crate::LOG2_E
429    }
430
431    fn PI() -> Self {
432        crate::PI
433    }
434
435    fn SQRT_2() -> Self {
436        crate::SQRT_2
437    }
438}
439
440impl FromPrimitive for BigFloat {
441    fn from_i64(n: i64) -> Option<Self> {
442        Some(BigFloat::from_i64(n))
443    }
444
445    fn from_u64(n: u64) -> Option<Self> {
446        Some(BigFloat::from_u64(n))
447    }
448
449    fn from_i128(n: i128) -> Option<Self> {
450        Some(BigFloat::from_i128(n))
451    }
452
453    fn from_u128(n: u128) -> Option<Self> {
454        Some(BigFloat::from_u128(n))
455    }
456
457    fn from_f32(n: f32) -> Option<Self> {
458        Some(BigFloat::from_f32(n))
459    }
460
461    fn from_f64(n: f64) -> Option<Self> {
462        Some(BigFloat::from_f64(n))
463    }
464}
465
466impl Inv for BigFloat {
467    type Output = BigFloat;
468
469    fn inv(self) -> Self::Output {
470        ONE.div(&self)
471    }
472}
473
474/// This trait is provided only for compatibility. It does not provide performance benefits.
475impl MulAdd for BigFloat {
476    type Output = BigFloat;
477
478    fn mul_add(self, a: Self, b: Self) -> Self::Output {
479        self.mul(&a).add(&b)
480    }
481}
482
483/// This trait is provided only for compatibility. It does not provide performance benefits.
484impl MulAddAssign for BigFloat {
485    fn mul_add_assign(&mut self, a: Self, b: Self) {
486        *self = self.mul(&a).add(&b)
487    }
488}
489
490impl Pow<BigFloat> for BigFloat {
491    type Output = BigFloat;
492
493    fn pow(self, rhs: BigFloat) -> Self::Output {
494        BigFloat::pow(&self, &rhs)
495    }
496}
497
498impl Signed for BigFloat {
499    /// Note: BigFloat NaN has no sign.
500    fn abs(&self) -> Self {
501        BigFloat::abs(self)
502    }
503
504    fn abs_sub(&self, other: &Self) -> Self {
505        let ret = self.sub(other);
506        if ret.is_negative() {
507            ZERO
508        } else {
509            ret
510        }
511    }
512
513    /// Note: BigFloat NaN has no sign.
514    fn signum(&self) -> Self {
515        let ret = BigFloat::signum(self);
516        if ret.is_zero() {
517            ONE
518        } else {
519            ret
520        }
521    }
522
523    fn is_positive(&self) -> bool {
524        self.is_positive() && !self.is_zero()
525    }
526
527    fn is_negative(&self) -> bool {
528        self.is_negative() && !self.is_zero()
529    }
530}
531
532impl Euclid for BigFloat {
533    fn div_euclid(&self, v: &BigFloat) -> BigFloat {
534        let q = BigFloat::int(&self.div(&v));
535        if BigFloat::rem(self, v).is_negative() {
536            return if v.is_negative() { q.add(&ONE) } else { q.sub(&ONE) };
537        }
538        q
539    }
540
541    fn rem_euclid(&self, v: &BigFloat) -> BigFloat {
542        let r = BigFloat::rem(self, v);
543        if r.is_negative() {
544            v.abs().add(&r)
545        } else {
546            r
547        }
548    }
549}
550
551#[cfg(not(feature = "std"))]
552impl FloatCore for BigFloat {
553    fn infinity() -> Self {
554        INF_POS
555    }
556
557    fn neg_infinity() -> Self {
558        INF_NEG
559    }
560
561    fn nan() -> Self {
562        NAN
563    }
564
565    fn neg_zero() -> Self {
566        ZERO
567    }
568
569    fn min_value() -> Self {
570        MIN
571    }
572
573    fn min_positive_value() -> Self {
574        MIN_POSITIVE_NORMAL
575    }
576
577    fn epsilon() -> Self {
578        EPSILON
579    }
580
581    fn max_value() -> Self {
582        MAX
583    }
584
585    fn classify(self) -> FpCategory {
586        BigFloat::classify(&self)
587    }
588
589    fn to_degrees(self) -> Self {
590        self.mul(&RAD_TO_DEG_FACTOR)
591    }
592
593    fn to_radians(self) -> Self {
594        self.div(&RAD_TO_DEG_FACTOR)
595    }
596
597    fn integer_decode(self) -> (u64, i16, i8) {
598        let f = self.to_f64();
599
600        let bits: u64 = f.to_bits();
601
602        let sign: i8 = if bits >> 63 == 0 { 1 } else { -1 };
603
604        let mut exponent: i16 = ((bits >> 52) & 0x7ff) as i16;
605
606        let mantissa = if exponent == 0 {
607            (bits & 0xfffffffffffff) << 1
608        } else {
609            (bits & 0xfffffffffffff) | 0x10000000000000
610        };
611
612        exponent -= 1023 + 52;
613
614        (mantissa, exponent, sign)
615    }
616}
617
618#[cfg(test)]
619mod tests {
620
621    use crate::{
622        BigFloat, RoundingMode, E, EPSILON, HALF_PI, INF_NEG, INF_POS, MIN_POSITIVE,
623        MIN_POSITIVE_NORMAL, NAN, ONE, PI, TWO,
624    };
625    use core::num::FpCategory;
626    use num_traits::{
627        Bounded, Euclid, FloatConst, FromPrimitive, Inv, MulAdd, MulAddAssign, Num, NumCast, Pow,
628        Signed, ToPrimitive, Zero,
629    };
630
631    #[cfg(feature = "std")]
632    use num_traits::Float;
633
634    #[cfg(not(feature = "std"))]
635    use num_traits::float::FloatCore;
636
637    #[test]
638    fn test_num_traits() {
639        // Num
640        let s1 = "1.234";
641        let d1 = BigFloat::from_str_radix(s1, 10).unwrap();
642        let d2 = BigFloat::parse(s1).unwrap();
643        assert!(d1.cmp(&d2) == Some(0));
644        assert!(BigFloat::from_str_radix(s1, 123).is_err());
645
646        // Float
647        #[cfg(feature = "std")]
648        {
649            let nan = <BigFloat as Float>::nan();
650            assert!(Float::is_nan(nan));
651            assert!(!Float::is_nan(d1));
652
653            let infinity = <BigFloat as Float>::infinity();
654            assert!(Float::is_infinite(infinity));
655            assert!(!Float::is_finite(infinity));
656            assert!(infinity > <BigFloat as Bounded>::max_value());
657
658            let neg_infinity = <BigFloat as Float>::neg_infinity();
659            assert!(neg_infinity.is_infinite());
660            assert!(!neg_infinity.is_finite());
661            assert!(neg_infinity < <BigFloat as Bounded>::min_value());
662
663            let zero = <BigFloat as Zero>::zero();
664            let neg_zero = <BigFloat as Float>::neg_zero();
665
666            assert_eq!(zero, neg_zero);
667            assert_eq!(BigFloat::from_f32(7.0) / infinity, zero);
668            assert_eq!(zero * BigFloat::from_f32(10.0), zero);
669
670            assert_eq!(
671                <BigFloat as Float>::min_value(),
672                <BigFloat as Bounded>::min_value()
673            );
674            assert_eq!(
675                <BigFloat as Float>::min_positive_value(),
676                MIN_POSITIVE_NORMAL
677            );
678            assert_eq!(
679                <BigFloat as Float>::max_value(),
680                <BigFloat as Bounded>::max_value()
681            );
682
683            assert!(<BigFloat as Float>::min_value().is_normal());
684            assert!(<BigFloat as Float>::max_value().is_normal());
685
686            let subnormal = MIN_POSITIVE;
687            assert!(!Float::is_normal(zero));
688            assert!(!Float::is_normal(nan));
689            assert!(!Float::is_normal(infinity));
690            assert!(!Float::is_normal(subnormal));
691
692            assert_eq!(Float::classify(d1), FpCategory::Normal);
693            assert_eq!(Float::classify(infinity), FpCategory::Infinite);
694            assert_eq!(Float::classify(nan), FpCategory::Nan);
695            assert_eq!(Float::classify(zero), FpCategory::Zero);
696            assert_eq!(Float::classify(subnormal), FpCategory::Subnormal);
697
698            let d1 = BigFloat::parse("3.3").unwrap();
699            let d2 = BigFloat::parse("3.0").unwrap();
700            assert_eq!(Float::floor(d1), d2);
701            assert_eq!(Float::floor(d2), d2);
702
703            let d1 = BigFloat::parse("3.3").unwrap();
704            let d2 = BigFloat::parse("4.0").unwrap();
705            assert_eq!(Float::ceil(d1), d2);
706            assert_eq!(Float::ceil(d2), d2);
707
708            let d1 = BigFloat::parse("3.3").unwrap();
709            let d2 = BigFloat::parse("3.0").unwrap();
710            assert_eq!(Float::round(d1), d2);
711
712            let d1 = BigFloat::parse("3.5").unwrap();
713            let d2 = BigFloat::parse("4.0").unwrap();
714            assert_eq!(Float::round(d1), d2);
715
716            let d1 = BigFloat::parse("-3.3").unwrap();
717            let d2 = BigFloat::parse("-3.0").unwrap();
718            assert_eq!(Float::round(d1), d2);
719
720            let d1 = BigFloat::parse("-3.5").unwrap();
721            let d2 = BigFloat::parse("-4.0").unwrap();
722            assert_eq!(Float::round(d1), d2);
723
724            let d1 = BigFloat::parse("3.7").unwrap();
725            let d2 = BigFloat::parse("3.0").unwrap();
726            assert_eq!(Float::trunc(d1), d2);
727
728            let d1 = BigFloat::parse("-3.7").unwrap();
729            let d2 = BigFloat::parse("-3.0").unwrap();
730            assert_eq!(Float::trunc(d1), d2);
731
732            let d1 = BigFloat::parse("-11.234").unwrap();
733            let d2 = BigFloat::parse("-0.234").unwrap();
734            assert_eq!(Float::fract(d1), d2);
735
736            let d1 = BigFloat::parse("-0.234").unwrap();
737            let d2 = BigFloat::parse("0.234").unwrap();
738            assert_eq!(Float::abs(d1), d2);
739            assert_eq!(Float::abs(d2), d2);
740
741            assert_eq!(Float::signum(d2), ONE);
742            assert_eq!(Float::signum(d1), -ONE);
743            assert_eq!(Float::signum(infinity), ONE);
744            assert_eq!(Float::signum(neg_infinity), -ONE);
745            assert!(Float::signum(nan).is_nan());
746
747            assert!(Float::is_sign_positive(d2));
748            assert!(Float::is_sign_positive(infinity));
749            assert!(!Float::is_sign_positive(d1));
750            assert!(!Float::is_sign_positive(neg_infinity));
751            assert!(!Float::is_sign_positive(nan));
752            assert!(Float::is_sign_negative(d1));
753            assert!(Float::is_sign_negative(neg_infinity));
754            assert!(!Float::is_sign_negative(d2));
755            assert!(!Float::is_sign_negative(infinity));
756            assert!(!Float::is_sign_negative(nan));
757
758            let d1 = BigFloat::parse("-2.1").unwrap();
759            let d2 = BigFloat::parse("3.34").unwrap();
760            let d3 = BigFloat::parse("43.657").unwrap();
761            assert_eq!(Float::mul_add(d1, d2, d3), d1 * d2 + d3);
762
763            assert_eq!(Float::recip(d1), ONE / d1);
764
765            let d1 = BigFloat::parse("3.0").unwrap();
766            let d2 = BigFloat::parse("81.0").unwrap();
767            let d3 = BigFloat::parse("4.0").unwrap();
768            assert_eq!(Float::powi(d1, 4), d2);
769            assert_eq!(Float::powf(d1, d3), d2);
770
771            let d1 = BigFloat::parse("9.0").unwrap();
772            let d2 = BigFloat::parse("3.0").unwrap();
773            assert_eq!(Float::sqrt(d1), d2);
774
775            let d1 = BigFloat::parse("3.0").unwrap();
776            assert!(Float::exp(d1).sub(&E.powf(d1)).get_exponent() <= -38);
777
778            let d1 = BigFloat::parse("3.0").unwrap();
779            let d2 = BigFloat::parse("2.0").unwrap();
780            assert!(Float::exp2(d1).sub(&d2.powf(d1)).abs() <= EPSILON);
781
782            let d2 = BigFloat::parse("4.0").unwrap();
783            assert_eq!(Float::ln(d1), BigFloat::ln(&d1));
784            assert_eq!(Float::log10(d1), BigFloat::log10(&d1));
785            assert_eq!(Float::log2(d1), BigFloat::log2(&d1));
786            assert_eq!(Float::log(d1, d2), BigFloat::log(&d1, &d2));
787
788            assert_eq!(Float::max(d1, d2), d2);
789            assert_eq!(Float::min(d1, d2), d1);
790
791            let d1 = -d1;
792            let d2 = -d2;
793            assert_eq!(Float::max(d1, d2), d1);
794            assert_eq!(Float::min(d1, d2), d2);
795
796            let d1 = BigFloat::parse("3.0").unwrap();
797            let d2 = BigFloat::parse("4.0").unwrap();
798            assert!(Float::abs_sub(d1, d2).is_zero());
799            assert_eq!(Float::abs_sub(d2, d1), ONE);
800
801            let d2 = BigFloat::parse("27.0").unwrap();
802            assert!(Float::cbrt(d2).sub(&d1).abs() <= EPSILON);
803
804            let d1 = BigFloat::parse("3.0").unwrap();
805            let d2 = BigFloat::parse("4.0").unwrap();
806            let d3 = BigFloat::parse("5.0").unwrap();
807            assert!(Float::hypot(d2, d1).sub(&d3).abs() <= EPSILON);
808
809            let d1 = BigFloat::parse("0.5").unwrap();
810            assert_eq!(Float::sin(d1), BigFloat::sin(&d1));
811            assert_eq!(Float::cos(d1), BigFloat::cos(&d1));
812            assert_eq!(Float::sin_cos(d1), (BigFloat::sin(&d1), BigFloat::cos(&d1)));
813            assert_eq!(Float::tan(d1), BigFloat::tan(&d1));
814            assert_eq!(Float::asin(d1), BigFloat::asin(&d1));
815            assert_eq!(Float::acos(d1), BigFloat::acos(&d1));
816            assert_eq!(Float::atan(d1), BigFloat::atan(&d1));
817
818            let d1 = BigFloat::parse("1.5").unwrap();
819            assert_eq!(Float::sinh(d1), BigFloat::sinh(&d1));
820            assert_eq!(Float::cosh(d1), BigFloat::cosh(&d1));
821            assert_eq!(Float::tanh(d1), BigFloat::tanh(&d1));
822            assert_eq!(Float::asinh(d1), BigFloat::asinh(&d1));
823            assert_eq!(Float::acosh(d1), BigFloat::acosh(&d1));
824            let d1 = BigFloat::parse("0.5").unwrap();
825            assert_eq!(Float::atanh(d1), BigFloat::atanh(&d1));
826
827            let d1 = BigFloat::parse("0.0").unwrap();
828            let d2 = BigFloat::parse("0.0").unwrap();
829            assert!(Float::atan2(d1, d2).is_zero());
830
831            let d1 = BigFloat::parse("2.0").unwrap();
832            let d2 = BigFloat::parse("3.0").unwrap();
833            assert_eq!(Float::atan2(d1, d2), d1.div(&d2).atan());
834
835            let d1 = BigFloat::parse("2.0").unwrap();
836            let d2 = BigFloat::parse("-3.0").unwrap();
837            assert_eq!(Float::atan2(d1, d2), d1.div(&d2).atan().add(&PI));
838
839            let d1 = BigFloat::parse("-2.0").unwrap();
840            let d2 = BigFloat::parse("-3.0").unwrap();
841            assert_eq!(Float::atan2(d1, d2), d1.div(&d2).atan().sub(&PI));
842
843            let d1 = BigFloat::parse("2.0").unwrap();
844            let d2 = BigFloat::parse("0.0").unwrap();
845            assert_eq!(Float::atan2(d1, d2), HALF_PI);
846
847            let d1 = BigFloat::parse("-2.0").unwrap();
848            let d2 = BigFloat::parse("0.0").unwrap();
849            assert_eq!(Float::atan2(d1, d2), -HALF_PI);
850
851            assert_eq!(Float::exp_m1(d1), BigFloat::exp(&d1).sub(&ONE));
852            assert_eq!(Float::ln_1p(E), BigFloat::ln(&E.add(&ONE)));
853
854            assert_eq!(Float::integer_decode(d1), Float::integer_decode(-2.0f64));
855        }
856
857        // FloatCore
858        #[cfg(not(feature = "std"))]
859        {
860            let nan = <BigFloat as FloatCore>::nan();
861            assert!(FloatCore::is_nan(nan));
862            assert!(!FloatCore::is_nan(d1));
863
864            let infinity = <BigFloat as FloatCore>::infinity();
865            assert!(FloatCore::is_infinite(infinity));
866            assert!(!FloatCore::is_finite(infinity));
867            assert!(infinity > <BigFloat as Bounded>::max_value());
868
869            let neg_infinity = <BigFloat as FloatCore>::neg_infinity();
870            assert!(neg_infinity.is_infinite());
871            assert!(!neg_infinity.is_finite());
872            assert!(neg_infinity < <BigFloat as Bounded>::min_value());
873
874            let zero = <BigFloat as Zero>::zero();
875            let neg_zero = <BigFloat as FloatCore>::neg_zero();
876
877            assert_eq!(zero, neg_zero);
878            assert_eq!(BigFloat::from_f32(7.0) / infinity, zero);
879            assert_eq!(zero * BigFloat::from_f32(10.0), zero);
880
881            assert_eq!(
882                <BigFloat as FloatCore>::min_value(),
883                <BigFloat as Bounded>::min_value()
884            );
885            assert_eq!(
886                <BigFloat as FloatCore>::min_positive_value(),
887                MIN_POSITIVE_NORMAL
888            );
889            assert_eq!(
890                <BigFloat as FloatCore>::max_value(),
891                <BigFloat as Bounded>::max_value()
892            );
893
894            assert!(<BigFloat as FloatCore>::min_value().is_normal());
895            assert!(<BigFloat as FloatCore>::max_value().is_normal());
896
897            let subnormal = MIN_POSITIVE;
898            assert!(!FloatCore::is_normal(zero));
899            assert!(!FloatCore::is_normal(nan));
900            assert!(!FloatCore::is_normal(infinity));
901            assert!(!FloatCore::is_normal(subnormal));
902
903            assert_eq!(FloatCore::classify(d1), FpCategory::Normal);
904            assert_eq!(FloatCore::classify(infinity), FpCategory::Infinite);
905            assert_eq!(FloatCore::classify(nan), FpCategory::Nan);
906            assert_eq!(FloatCore::classify(zero), FpCategory::Zero);
907            assert_eq!(FloatCore::classify(subnormal), FpCategory::Subnormal);
908
909            let d1 = BigFloat::parse("3.3").unwrap();
910            let d2 = BigFloat::parse("3.0").unwrap();
911            assert_eq!(FloatCore::floor(d1), d2);
912            assert_eq!(FloatCore::floor(d2), d2);
913
914            let d1 = BigFloat::parse("3.3").unwrap();
915            let d2 = BigFloat::parse("4.0").unwrap();
916            assert_eq!(FloatCore::ceil(d1), d2);
917            assert_eq!(FloatCore::ceil(d2), d2);
918
919            let d1 = BigFloat::parse("3.3").unwrap();
920            let d2 = BigFloat::parse("3.0").unwrap();
921            assert_eq!(FloatCore::round(d1), d2);
922
923            let d1 = BigFloat::parse("3.5").unwrap();
924            let d2 = BigFloat::parse("4.0").unwrap();
925            assert_eq!(FloatCore::round(d1), d2);
926
927            let d1 = BigFloat::parse("-3.3").unwrap();
928            let d2 = BigFloat::parse("-3.0").unwrap();
929            assert_eq!(FloatCore::round(d1), d2);
930
931            let d1 = BigFloat::parse("-3.5").unwrap();
932            let d2 = BigFloat::parse("-4.0").unwrap();
933            assert_eq!(FloatCore::round(d1), d2);
934
935            let d1 = BigFloat::parse("3.7").unwrap();
936            let d2 = BigFloat::parse("3.0").unwrap();
937            assert_eq!(FloatCore::trunc(d1), d2);
938
939            let d1 = BigFloat::parse("-3.7").unwrap();
940            let d2 = BigFloat::parse("-3.0").unwrap();
941            assert_eq!(FloatCore::trunc(d1), d2);
942
943            let d1 = BigFloat::parse("-11.234").unwrap();
944            let d2 = BigFloat::parse("-0.234").unwrap();
945            assert_eq!(FloatCore::fract(d1), d2);
946
947            let d1 = BigFloat::parse("-0.234").unwrap();
948            let d2 = BigFloat::parse("0.234").unwrap();
949            assert_eq!(FloatCore::abs(d1), d2);
950            assert_eq!(FloatCore::abs(d2), d2);
951
952            assert_eq!(FloatCore::signum(d2), ONE);
953            assert_eq!(FloatCore::signum(d1), -ONE);
954            assert_eq!(FloatCore::signum(infinity), ONE);
955            assert_eq!(FloatCore::signum(neg_infinity), -ONE);
956            assert!(FloatCore::signum(nan).is_nan());
957
958            assert!(FloatCore::is_sign_positive(d2));
959            assert!(FloatCore::is_sign_positive(infinity));
960            assert!(!FloatCore::is_sign_positive(d1));
961            assert!(!FloatCore::is_sign_positive(neg_infinity));
962            assert!(FloatCore::is_sign_positive(nan));
963            assert!(FloatCore::is_sign_negative(d1));
964            assert!(FloatCore::is_sign_negative(neg_infinity));
965            assert!(!FloatCore::is_sign_negative(d2));
966            assert!(!FloatCore::is_sign_negative(infinity));
967            assert!(!FloatCore::is_sign_negative(nan));
968
969            let d1 = BigFloat::parse("90.0").unwrap();
970            assert!(FloatCore::to_radians(d1).sub(&HALF_PI).abs() <= EPSILON);
971            assert!(
972                FloatCore::to_degrees(HALF_PI).sub(&d1).abs() <= EPSILON * BigFloat::from_u8(20)
973            );
974
975            let d1 = BigFloat::parse("-123.123").unwrap();
976            assert_eq!(FloatCore::to_radians(d1).to_degrees(), d1);
977
978            let d1 = BigFloat::parse("-2.0").unwrap();
979            assert_eq!(
980                FloatCore::integer_decode(d1),
981                FloatCore::integer_decode(-2.0f64)
982            );
983        }
984
985        // FloatConst
986        assert!(
987            <BigFloat as FloatConst>::SQRT_2()
988                .mul(&FloatConst::SQRT_2())
989                .sub(&TWO)
990                <= EPSILON
991        );
992        assert!(<BigFloat as FloatConst>::FRAC_1_PI().mul(&PI).sub(&ONE) <= EPSILON);
993        assert!(
994            <BigFloat as FloatConst>::FRAC_1_SQRT_2()
995                .mul(&<BigFloat as FloatConst>::SQRT_2())
996                .sub(&ONE)
997                <= EPSILON
998        );
999        assert!(<BigFloat as FloatConst>::FRAC_2_PI().mul(&PI).sub(&TWO) <= EPSILON);
1000        assert!(
1001            <BigFloat as FloatConst>::FRAC_2_SQRT_PI()
1002                .mul(&PI.sqrt())
1003                .sub(&TWO)
1004                <= EPSILON
1005        );
1006        assert!(<BigFloat as FloatConst>::FRAC_PI_2().mul(&TWO).sub(&PI) <= EPSILON);
1007        assert!(
1008            <BigFloat as FloatConst>::FRAC_PI_3()
1009                .mul(&BigFloat::from_i8(3))
1010                .sub(&PI)
1011                <= EPSILON
1012        );
1013        assert!(
1014            <BigFloat as FloatConst>::FRAC_PI_4()
1015                .mul(&BigFloat::from_i8(4))
1016                .sub(&PI)
1017                <= EPSILON
1018        );
1019        assert!(
1020            <BigFloat as FloatConst>::FRAC_PI_6()
1021                .mul(&BigFloat::from_i8(6))
1022                .sub(&PI)
1023                <= EPSILON
1024        );
1025        assert!(
1026            <BigFloat as FloatConst>::FRAC_PI_8()
1027                .mul(&BigFloat::from_i8(8))
1028                .sub(&PI)
1029                <= EPSILON
1030        );
1031        assert!(<BigFloat as FloatConst>::LN_10().sub(&BigFloat::from_i8(10).ln()) <= EPSILON);
1032        assert!(<BigFloat as FloatConst>::LN_2().sub(&TWO.ln()) <= EPSILON);
1033        assert!(<BigFloat as FloatConst>::LOG10_E().sub(&E.log10()) <= EPSILON);
1034        assert!(<BigFloat as FloatConst>::LOG2_E().sub(&E.log2()) <= EPSILON);
1035
1036        // Euclid
1037        let a = BigFloat::from_i8(7);
1038        let b = BigFloat::from_i8(4);
1039        assert_eq!(Euclid::div_euclid(&a, &b), ONE); // 7 > 4 * 1
1040        assert_eq!(Euclid::div_euclid(&-a, &b), -TWO); // -7 >= 4 * -2
1041        assert_eq!(Euclid::div_euclid(&a, &-b), -ONE); // 7 >= -4 * -1
1042        assert_eq!(Euclid::div_euclid(&-a, &-b), TWO); // -7 >= -4 * 2
1043
1044        let c = BigFloat::from_i8(3);
1045        assert_eq!(Euclid::rem_euclid(&a, &b), c);
1046        assert_eq!(Euclid::rem_euclid(&-a, &b), ONE);
1047        assert_eq!(Euclid::rem_euclid(&a, &-b), c);
1048        assert_eq!(Euclid::rem_euclid(&-a, &-b), ONE);
1049
1050        // MulAdd
1051        let d1 = BigFloat::parse("-2.1").unwrap();
1052        let d2 = BigFloat::parse("3.34").unwrap();
1053        let d3 = BigFloat::parse("43.657").unwrap();
1054        assert_eq!(MulAdd::mul_add(d1, d2, d3), d1 * d2 + d3);
1055
1056        // MulAssign
1057        let mut d1 = BigFloat::parse("-2.1").unwrap();
1058        let d2 = BigFloat::parse("3.34").unwrap();
1059        let d3 = BigFloat::parse("43.657").unwrap();
1060        let ret = d1 * d2 + d3;
1061        MulAddAssign::mul_add_assign(&mut d1, d2, d3);
1062        assert_eq!(d1, ret);
1063
1064        // Inv
1065        let d1 = BigFloat::parse("-2.1").unwrap();
1066        assert_eq!(Inv::inv(d1), ONE / d1);
1067
1068        // Signed
1069        let d1 = BigFloat::parse("-0.234").unwrap();
1070        let d2 = BigFloat::parse("0.234").unwrap();
1071        assert_eq!(Signed::abs(&d1), d2);
1072        assert_eq!(Signed::abs(&d2), d2);
1073
1074        let d1 = BigFloat::parse("3.0").unwrap();
1075        let d2 = BigFloat::parse("4.0").unwrap();
1076        assert!(Signed::abs_sub(&d1, &d2).is_zero());
1077        assert_eq!(Signed::abs_sub(&d2, &d1), ONE);
1078
1079        let d1 = -d1;
1080        assert_eq!(Signed::signum(&d2), ONE);
1081        assert_eq!(Signed::signum(&d1), -ONE);
1082        assert_eq!(Signed::signum(&INF_POS), ONE);
1083        assert_eq!(Signed::signum(&INF_NEG), -ONE);
1084        assert!(Signed::signum(&NAN).is_nan());
1085
1086        assert!(Signed::is_positive(&BigFloat::from_i8(12)));
1087        assert!(Signed::is_positive(&INF_POS));
1088        assert!(!Signed::is_positive(&BigFloat::from_i8(0)));
1089        assert!(!Signed::is_positive(&INF_NEG));
1090        assert!(!Signed::is_positive(&NAN));
1091
1092        assert!(Signed::is_negative(&BigFloat::from_i8(-12)));
1093        assert!(Signed::is_negative(&INF_NEG));
1094        assert!(!Signed::is_negative(&BigFloat::from_i8(0)));
1095        assert!(!Signed::is_negative(&INF_POS));
1096        assert!(!Signed::is_negative(&NAN));
1097
1098        // Pow
1099        let d1 = BigFloat::parse("3.45").unwrap();
1100        let d2 = BigFloat::parse("-4.567").unwrap();
1101        assert_eq!(Pow::pow(d1, d2), BigFloat::pow(&d1, &d2));
1102
1103        // ToPrimitive
1104        let d1 = BigFloat::parse("-356798765.45678").unwrap();
1105        assert_eq!(ToPrimitive::to_i64(&d1), Some(-356798765));
1106        assert_eq!(ToPrimitive::to_u64(&d1), Some(356798765));
1107        assert_eq!(ToPrimitive::to_i128(&d1), Some(-356798765));
1108        assert_eq!(ToPrimitive::to_u128(&d1), Some(356798765));
1109        assert_eq!(ToPrimitive::to_f32(&d1), Some(-356798765.45678));
1110        assert_eq!(ToPrimitive::to_f64(&d1), Some(-356798765.45678));
1111
1112        // NumCast
1113        assert_eq!(NumCast::from(1i8), Some(ONE));
1114        assert_eq!(NumCast::from(1u8), Some(ONE));
1115        let d2: BigFloat = NumCast::from(-356798765.45678f64).unwrap();
1116        assert_eq!(d2, d1);
1117
1118        let d1 = BigFloat::parse("5.45678").unwrap();
1119        let d2: BigFloat = NumCast::from(5.45678f32).unwrap();
1120        assert_eq!(BigFloat::round(&d2, 5, RoundingMode::ToEven), d1);
1121
1122        // FromPrimitive
1123        let d1 = BigFloat::parse("-356798765").unwrap();
1124        assert_eq!(FromPrimitive::from_i64(-356798765), Some(d1));
1125        assert_eq!(FromPrimitive::from_u64(356798765), Some(-d1));
1126        assert_eq!(FromPrimitive::from_i128(-356798765), Some(d1));
1127        assert_eq!(FromPrimitive::from_u128(356798765), Some(-d1));
1128        let d1 = BigFloat::parse("-5.45678").unwrap();
1129        let d2 = FromPrimitive::from_f32(-5.45678f32).unwrap();
1130        let d2 = BigFloat::round(&d2, 5, RoundingMode::ToEven);
1131        assert_eq!(d2, d1);
1132        let d1 = BigFloat::parse("-356798765.45678").unwrap();
1133        assert_eq!(FromPrimitive::from_f64(-356798765.45678f64), Some(d1));
1134    }
1135}