1use 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
24pub const MAX: BigFloat = BigFloat {
26 inner: Flavor::Value(crate::defs::MAX),
27};
28
29pub const MAX_EXP: i8 = DECIMAL_MAX_EXPONENT;
31
32pub const MIN: BigFloat = BigFloat {
34 inner: Flavor::Value(crate::defs::MIN),
35};
36
37pub const MIN_EXP: i8 = DECIMAL_MIN_EXPONENT;
39
40pub const MIN_POSITIVE: BigFloat = BigFloat {
42 inner: Flavor::Value(crate::defs::MIN_POSITIVE),
43};
44
45pub const MIN_POSITIVE_NORMAL: BigFloat = BigFloat {
47 inner: Flavor::Value(crate::defs::MIN_POSITIVE_NORMAL),
48};
49
50pub const RADIX: u32 = 10;
52
53pub const NAN: BigFloat = BigFloat { inner: Flavor::NaN };
55
56pub const INF_POS: BigFloat = BigFloat {
58 inner: Flavor::Inf(DECIMAL_SIGN_POS),
59};
60
61pub const INF_NEG: BigFloat = BigFloat {
63 inner: Flavor::Inf(DECIMAL_SIGN_NEG),
64};
65
66pub const ZERO: BigFloat = BigFloat {
68 inner: Flavor::Value(crate::defs::ZERO),
69};
70
71pub const ONE: BigFloat = BigFloat {
73 inner: Flavor::Value(crate::defs::ONE),
74};
75
76pub const TWO: BigFloat = BigFloat {
78 inner: Flavor::Value(crate::defs::TWO),
79};
80
81pub const E: BigFloat = BigFloat {
83 inner: Flavor::Value(crate::defs::E),
84};
85
86pub const PI: BigFloat = BigFloat {
88 inner: Flavor::Value(crate::defs::PI),
89};
90
91pub 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
101pub 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
111pub 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
121pub 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
131pub 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
141pub 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
151pub 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
161pub 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
171pub 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
181pub 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
191pub 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
201pub 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
211pub 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
221pub 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
231pub 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#[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#[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), }
267
268impl BigFloat {
269 pub fn new() -> Self {
271 BigFloat {
272 inner: Flavor::Value(BigFloatNum::new()),
273 }
274 }
275
276 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 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); write!(strepr, "{:e}", f).unwrap();
308 Self::parse(core::str::from_utf8(&buf).unwrap()).unwrap()
309 }
310 }
311
312 pub fn from_f32(f: f32) -> Self {
315 Self::from_f64(f as f64)
316 }
317
318 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 pub fn to_f32(&self) -> f32 {
342 self.to_f64() as f32
343 }
344
345 pub fn to_i64(&self) -> Option<i64> {
348 self.to_int::<i64>(&I64_MIN, &I64_MAX)
349 }
350
351 pub fn to_i128(&self) -> Option<i128> {
354 self.to_int::<i128>(&I128_MIN, &I128_MAX)
355 }
356
357 pub fn to_u64(&self) -> Option<u64> {
360 self.to_uint::<u64>(&U64_MAX)
361 }
362
363 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 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 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 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 pub fn get_exponent(&self) -> i8 {
518 match self.inner {
519 Flavor::Value(v) => v.e,
520 _ => 0,
521 }
522 }
523
524 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 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 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 pub fn is_inf_pos(&self) -> bool {
563 matches!(self.inner, Flavor::Inf(DECIMAL_SIGN_POS))
564 }
565
566 pub fn is_inf_neg(&self) -> bool {
568 matches!(self.inner, Flavor::Inf(DECIMAL_SIGN_NEG))
569 }
570
571 pub fn is_inf(&self) -> bool {
573 self.is_inf_pos() || self.is_inf_neg()
574 }
575
576 pub fn is_nan(&self) -> bool {
578 matches!(self.inner, Flavor::NaN)
579 }
580
581 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 NAN
846 } else {
847 match b.inner {
848 Flavor::Value(v2) => {
849 let val = v2.cmp(&BigFloatNum::one());
851 if val < 0 {
852 INF_NEG
853 } else {
854 INF_POS
855 }
856 }
857 Flavor::Inf(_) => NAN, 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 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 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 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 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 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 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 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 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 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 #[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 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 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 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 pub fn rem(&self, d1: &Self) -> Self {
1145 self.sub(&(self.div(&d1)).int().mul(&d1))
1146 }
1147}
1148
1149macro_rules! gen_wrapper2 {
1150 ($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 ($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
1336pub 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 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 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 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 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 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 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 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 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}