1#[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 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 fn is_sign_positive(self) -> bool {
195 BigFloat::is_positive(&self)
196 }
197
198 fn is_sign_negative(self) -> bool {
200 BigFloat::is_negative(&self)
201 }
202
203 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 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 fn sin_cos(self) -> (Self, Self) {
315 (BigFloat::sin(&self), BigFloat::cos(&self))
316 }
317
318 fn exp_m1(self) -> Self {
320 self.exp().sub(&ONE)
321 }
322
323 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 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
474impl 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
483impl 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 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 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 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 #[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 #[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 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 let a = BigFloat::from_i8(7);
1038 let b = BigFloat::from_i8(4);
1039 assert_eq!(Euclid::div_euclid(&a, &b), ONE); assert_eq!(Euclid::div_euclid(&-a, &b), -TWO); assert_eq!(Euclid::div_euclid(&a, &-b), -ONE); assert_eq!(Euclid::div_euclid(&-a, &-b), TWO); 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 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 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 let d1 = BigFloat::parse("-2.1").unwrap();
1066 assert_eq!(Inv::inv(d1), ONE / d1);
1067
1068 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 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 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 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 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}