1#![deny(missing_docs)]
64#![deny(clippy::suspicious)]
65#![cfg_attr(not(feature = "std"), no_std)]
66
67mod defs;
68mod ext;
69mod inc;
70mod ops;
71mod parser;
72mod util;
73
74#[cfg(feature = "num-traits")]
75mod num_traits;
76
77#[cfg(feature = "serde")]
78pub mod serde;
79
80pub use crate::defs::Error;
81pub use crate::defs::RoundingMode;
82pub use crate::ext::BigFloat;
83pub use crate::ext::E;
84pub use crate::ext::EPSILON;
85pub use crate::ext::FRAC_1_PI;
86pub use crate::ext::FRAC_1_SQRT_2;
87pub use crate::ext::FRAC_2_PI;
88pub use crate::ext::FRAC_2_SQRT_PI;
89pub use crate::ext::FRAC_PI_3;
90pub use crate::ext::FRAC_PI_4;
91pub use crate::ext::FRAC_PI_6;
92pub use crate::ext::FRAC_PI_8;
93pub use crate::ext::HALF_PI;
94pub use crate::ext::INF_NEG;
95pub use crate::ext::INF_POS;
96pub use crate::ext::LN_10;
97pub use crate::ext::LN_2;
98pub use crate::ext::LOG10_E;
99pub use crate::ext::LOG2_E;
100pub use crate::ext::MAX;
101pub use crate::ext::MAX_EXP;
102pub use crate::ext::MIN;
103pub use crate::ext::MIN_EXP;
104pub use crate::ext::MIN_POSITIVE;
105pub use crate::ext::MIN_POSITIVE_NORMAL;
106pub use crate::ext::NAN;
107pub use crate::ext::ONE;
108pub use crate::ext::PI;
109pub use crate::ext::RADIX;
110pub use crate::ext::SQRT_2;
111pub use crate::ext::TWO;
112pub use crate::ext::ZERO;
113
114#[cfg(test)]
115mod tests {
116
117 use crate::defs::{
118 DECIMAL_BASE, DECIMAL_MAX_EXPONENT, DECIMAL_MIN_EXPONENT, DECIMAL_PARTS, DECIMAL_POSITIONS,
119 DECIMAL_SIGN_NEG, DECIMAL_SIGN_POS,
120 };
121 use crate::{
122 BigFloat, HALF_PI, INF_NEG, INF_POS, MAX, MIN, MIN_POSITIVE, NAN, ONE, PI, TWO, ZERO,
123 };
124 use rand::random;
125
126 #[test]
127 fn test_lib_basic() {
128 let mut d1;
129 let mut d2;
130 let mut d3;
131 let mut ref_num;
132
133 let bytes1: [u8; 20] =
137 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 112, 13, 14, 15, 16, 17, 18, 19, 20];
138 let expected1: [u8; 30] = [
139 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
140 0,
141 ];
142 let exp1 = 123;
143 let d4 = BigFloat::from_bytes(&bytes1, 1, exp1);
144
145 let mut mantissa_buf1 = [0; 30];
146 d4.get_mantissa_bytes(&mut mantissa_buf1);
147 assert!(mantissa_buf1 == expected1);
148 assert!(d4.get_mantissa_len() == bytes1.len());
149 assert!(d4.get_sign() == 1);
150 assert!(d4.get_exponent() == exp1);
151
152 let bytes2: [u8; 45] = [
154 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 112, 13, 14, 15, 16, 17, 18, 19, 20, 1, 2, 3, 4, 5,
155 6, 7, 8, 9, 10, 11, 112, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 3, 4, 5,
156 ];
157 let expected2: [u8; 42] = [
158 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
159 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0,
160 ];
161 let exp2 = -128;
162 let d4 = BigFloat::from_bytes(&bytes2, -2, exp2);
163
164 let mut mantissa_buf2 = [0; 42];
165 d4.get_mantissa_bytes(&mut mantissa_buf2);
166 assert!(mantissa_buf2 == expected2);
167 assert!(d4.get_mantissa_len() == 40);
168 assert!(d4.get_sign() == -1);
169 assert!(d4.get_exponent() == exp2);
170
171 assert!(BigFloat::from_f64(f64::INFINITY).cmp(&INF_POS) == Some(0));
175 assert!(BigFloat::from_f64(f64::NEG_INFINITY).cmp(&INF_NEG) == Some(0));
176
177 assert!(BigFloat::from_f64(f64::NAN).is_nan());
179
180 assert!(BigFloat::from_f64(0.0).to_f64() == 0.0);
182
183 for _ in 0..10000 {
185 let f: f64 = random_f64_exp(50, 25);
186 if f.is_finite() && f != 0.0 {
187 d1 = BigFloat::from_f64(f);
188 assert!(d1.to_f64() == f);
189 if (f as f32).is_finite() && (f as f32) != 0.0 {
190 d1 = BigFloat::from_f32(f as f32);
191 assert!(d1.to_f32() == f as f32);
192 }
193 }
194 }
195
196 d1 = BigFloat::new();
198 d2 = BigFloat::new();
199 ref_num = BigFloat::new();
200 d3 = d1.mul(&d2);
201 assert!(d3.cmp(&ref_num) == Some(0));
202
203 d1 = BigFloat::from_f64(0.99);
205 d3 = d1.mul(&d2);
206 assert!(d3.cmp(&ref_num) == Some(0));
207
208 d1 = BigFloat::new();
210 d2 = BigFloat::from_u32(12349999);
211 d3 = d1.mul(&d2);
212 assert!(d3.cmp(&ref_num) == Some(0));
213
214 d1 = BigFloat::from_u8(1);
216 d2 = BigFloat::from_u8(1);
217 d3 = d1.mul(&d2);
218 assert!(d3.cmp(&d1) == Some(0));
219
220 d1 = BigFloat::from_u8(1);
222 d2 = BigFloat::from_u8(1).inv_sign();
223 d3 = d1.mul(&d2);
224 assert!(d3.cmp(&d2) == Some(0));
225
226 d3 = d2.mul(&d1);
228 assert!(d3.cmp(&d2) == Some(0));
229
230 d1 = d1.inv_sign();
232 d3 = d1.mul(&d2);
233 ref_num = BigFloat::from_u8(1);
234 assert!(d3.cmp(&ref_num) == Some(0));
235
236 d1 = BigFloat::new();
238 d2 = BigFloat::new();
239 assert!(d1.div(&d2).is_nan());
240
241 d2 = BigFloat::from_u8(123);
243 assert!(d2.div(&d1).is_inf_pos());
244
245 d3 = d1.div(&d2);
247 ref_num = BigFloat::new();
248 assert!(d3.cmp(&ref_num) == Some(0));
249
250 d2 = d2.inv_sign();
252 d3 = d1.div(&d2);
253 assert!(d3.cmp(&ref_num) == Some(0));
254 }
255
256 #[test]
257 fn test_lib_add_sub() {
258 let mut d1;
259 let mut d2;
260 let mut ref_num;
261
262 for _ in 0..10000 {
264 d1 = random_normal_float(4, 30);
266 d2 = random_normal_float(4, 34);
267 let n1 = d1.add(&d2);
268 let n2 = n1.sub(&d2);
269 assert_small(&n2.sub(&d1), 2, &d1);
270 }
271
272 for _ in 0..10000 {
274 d1 = random_normal_float(40, 40);
276 d2 = random_normal_float(40, 40);
277 if d2.cmp(&ZERO).unwrap() != 0 {
278 let n1 = d1.div(&d2);
279 let n2 = n1.mul(&d2);
280 assert_small(&n2.sub(&d1), 2, &d1);
281 }
282 }
283
284 d1 = MIN_POSITIVE;
286 d2 = MIN_POSITIVE;
287 ref_num = MIN_POSITIVE.mul(&TWO);
288
289 assert!(d1.add(&d2).cmp(&ref_num) == Some(0));
291 assert!(d1.add(&d2).cmp(&d1).unwrap() > 0);
292 assert!(d1.cmp(&d1.add(&d2)).unwrap() < 0);
293
294 ref_num = BigFloat::new();
296 assert!(d1.sub(&d2).cmp(&ref_num) == Some(0));
297
298 assert!(ONE.mul(&d2).cmp(&d2) == Some(0));
300
301 assert!(d2.div(&ONE).cmp(&d2) == Some(0));
303
304 assert!(d2.div(&ONE).cmp(&d2) == Some(0));
306
307 d1 = ONE;
309 d1.set_exponent(DECIMAL_MIN_EXPONENT);
310 d2 = MIN_POSITIVE;
311 assert!(!d1.is_subnormal());
312 assert!(d1.sub(&d2).cmp(&d1).unwrap() < 0);
313 assert!(d1.cmp(&d1.sub(&d2)).unwrap() > 0);
314 d1 = d1.sub(&d2);
315 assert!(d1.is_subnormal());
316 d1 = d1.add(&d2);
317 assert!(!d1.is_subnormal());
318
319 d1 = ONE;
321 d1.set_exponent(DECIMAL_MAX_EXPONENT - (DECIMAL_POSITIONS as i8 - 1));
322 assert!(MAX.add(&d1).is_inf_pos());
323 assert!(MIN.sub(&d1).is_inf_neg());
324 assert!(MAX.mul(&MAX).is_inf_pos());
325 d1 = ONE;
326 d1.set_exponent(DECIMAL_MIN_EXPONENT);
327 assert!(MAX.div(&d1).is_inf_pos());
328 }
329
330 #[test]
331 fn test_lib_fract_int_abs() {
332 let mut d1;
333
334 let f1 = 12345.6789;
336 d1 = BigFloat::from_f64(f1);
337 assert!((d1.frac().to_f64() - f1.fract()).abs() < 10000.0 * f64::EPSILON);
338 assert!((d1.int().to_f64() - (f1 as u64) as f64).abs() < 10000.0 * f64::EPSILON);
339
340 let f1 = -0.006789;
341 d1 = BigFloat::from_f64(f1);
342 assert!(d1.frac().cmp(&d1) == Some(0));
343 assert!(d1.int().is_zero());
344
345 d1 = BigFloat::from_bytes(&[2, 2, 2, 2, 2, 0, 0, 0], DECIMAL_SIGN_POS, -2);
346 assert!(d1.frac().is_zero());
347 assert!(d1.int().cmp(&d1) == Some(0));
348
349 assert!(MIN_POSITIVE.frac().cmp(&MIN_POSITIVE) == Some(0));
350 assert!(MIN_POSITIVE.int().is_zero());
351
352 d1 = BigFloat::new();
353 assert!(d1.frac().is_zero());
354 assert!(d1.int().is_zero());
355
356 d1 = BigFloat::from_f64(12.3);
358 assert!(d1.floor().to_f64() == 12.0);
359 assert!(d1.ceil().to_f64() == 13.0);
360 d1 = BigFloat::from_f64(12.0);
361 assert!(d1.floor().to_f64() == 12.0);
362 assert!(d1.ceil().to_f64() == 12.0);
363
364 d1 = BigFloat::from_f64(-12.3);
365 assert!(d1.floor().to_f64() == -13.0);
366 assert!(d1.ceil().to_f64() == -12.0);
367 d1 = BigFloat::from_f64(-12.0);
368 assert!(d1.floor().to_f64() == -12.0);
369 assert!(d1.ceil().to_f64() == -12.0);
370
371 d1 = BigFloat::from_f64(12.3);
373 assert!(d1.abs().to_f64() == 12.3);
374 d1 = BigFloat::from_f64(-12.3);
375 assert!(d1.abs().to_f64() == 12.3);
376 }
377
378 #[test]
379 fn test_lib_sqrt() {
380 for _ in 0..10000 {
382 let num = random_normal_float(256, 128).abs();
383 let sq = num.sqrt();
384 let ret = sq.mul(&sq);
385 assert_small(&num.sub(&ret), 2, &num);
386 }
387
388 let n = MAX.sqrt();
390 assert!(n.cmp(&ZERO).unwrap() > 0 && MAX.cmp(&n).unwrap() > 0);
391 let n = n.mul(&n);
392 assert_small_if_not(n.is_inf_pos(), &MAX.sub(&n), 2, &MAX);
393
394 let n = ZERO.sqrt();
396 assert!(n.cmp(&ZERO).unwrap() == 0);
397
398 let n = MIN_POSITIVE.sqrt();
400 assert!(n.cmp(&ZERO).unwrap() > 0 && MIN_POSITIVE.cmp(&n).unwrap() < 0);
401 let n = n.mul(&n);
402 assert_small_if_not(n.is_zero(), &MIN_POSITIVE.sub(&n), 2, &MIN_POSITIVE);
403
404 let n = MIN_POSITIVE.inv_sign().sqrt();
406 assert!(n.is_nan());
407 }
408
409 #[test]
410 fn test_lib_cbrt() {
411 for _ in 0..10000 {
413 let num = random_normal_float(256, 128);
414 let sq = num.cbrt();
415 let ret = sq.mul(&sq).mul(&sq);
416 assert_small(&num.sub(&ret), 2, &num);
417 }
418
419 let n = MAX.cbrt();
421 assert!(n.cmp(&ZERO).unwrap() > 0 && MAX.cmp(&n).unwrap() > 0);
422 let n = n.mul(&n).mul(&n);
423 assert_small_if_not(n.is_inf_pos(), &MAX.sub(&n), 2, &MAX);
424
425 let n = ZERO.cbrt();
427 assert!(n.cmp(&ZERO).unwrap() == 0);
428
429 let n = MIN_POSITIVE.cbrt();
431 assert!(n.cmp(&ZERO).unwrap() > 0 && MIN_POSITIVE.cmp(&n).unwrap() < 0);
432 let n = n.mul(&n).mul(&n);
433 assert_small_if_not(n.is_zero(), &MIN_POSITIVE.sub(&n), 2, &MIN_POSITIVE);
434
435 let n = MAX.inv_sign().cbrt();
437 assert!(n.cmp(&ZERO).unwrap() < 0 && MAX.inv_sign().cmp(&n).unwrap() < 0);
438 let n = n.mul(&n).mul(&n);
439 assert_small_if_not(n.is_inf_neg(), &MAX.inv_sign().sub(&n), 2, &MAX.inv_sign());
440
441 let n = MIN_POSITIVE.inv_sign().cbrt();
443 assert!(n.cmp(&ZERO).unwrap() < 0 && MIN_POSITIVE.inv_sign().cmp(&n).unwrap() > 0);
444 let n = n.mul(&n).mul(&n);
445 assert_small_if_not(
446 n.is_zero(),
447 &MIN_POSITIVE.inv_sign().sub(&n),
448 2,
449 &MIN_POSITIVE.inv_sign(),
450 );
451 }
452
453 #[test]
454 fn test_lib_pow() {
455 for _ in 0..10000 {
457 let a = random_normal_float(4, 40);
458 let n = random_normal_float(4, 40);
459 let inv = ONE.div(&n);
460 let p = a.pow(&n);
461 if !p.is_inf() && p.get_mantissa_len() >= DECIMAL_POSITIONS - 1 {
462 let ret = p.pow(&inv);
463 assert_small(&a.sub(&ret), 3, &a);
464 }
465 }
466
467 assert!(ONE.pow(&MIN_POSITIVE).cmp(&ONE).unwrap() == 0);
469 assert!(ONE.pow(&MIN_POSITIVE.inv_sign()).cmp(&ONE).unwrap() == 0);
470 assert!(ONE.pow(&MAX).cmp(&ONE).unwrap() == 0);
471 assert!(ONE.pow(&MIN).cmp(&ONE).unwrap() == 0);
472 assert!(ONE.pow(&TWO).cmp(&ONE).unwrap() == 0);
473 assert!(ONE.pow(&ONE.div(&TWO)).cmp(&ONE).unwrap() == 0);
474 assert!(ONE.pow(&ZERO).cmp(&ONE).unwrap() == 0);
475
476 assert!(TWO.pow(&MIN_POSITIVE).cmp(&ONE).unwrap() == 0);
478 assert!(TWO.pow(&MIN_POSITIVE.inv_sign()).cmp(&ONE).unwrap() == 0);
479 assert!(TWO.pow(&MAX).is_inf_pos());
480 assert!(TWO.pow(&MIN).is_zero());
481 assert!(TWO.pow(&ONE).cmp(&TWO).unwrap() == 0);
482 assert!(TWO.pow(&ZERO).cmp(&ONE).unwrap() == 0);
483
484 let n = ONE.div(&TWO);
486 assert!(n.pow(&MIN_POSITIVE).cmp(&ONE).unwrap() == 0);
487 assert!(n.pow(&MIN_POSITIVE.inv_sign()).cmp(&ONE).unwrap() == 0);
488 assert!(n.pow(&MAX).is_zero());
489 assert!(n.pow(&MIN).is_inf_pos());
490 assert!(n.pow(&ONE).cmp(&n).unwrap() == 0);
491 assert!(n.pow(&ZERO).cmp(&ONE).unwrap() == 0);
492
493 assert!(ZERO.pow(&MIN_POSITIVE).is_zero());
495 assert!(ZERO.pow(&MIN_POSITIVE.inv_sign()).is_inf_pos());
496 assert!(ZERO.pow(&MAX).is_zero());
497 assert!(ZERO.pow(&MIN).is_inf_pos());
498 assert!(ZERO.pow(&ONE).is_zero());
499 assert!(ZERO.pow(&ZERO).is_nan());
500
501 let n = TWO.inv_sign();
503 assert!(n.pow(&MIN_POSITIVE).cmp(&ONE.inv_sign()).unwrap() == 0);
504 assert!(
505 n.pow(&MIN_POSITIVE.inv_sign())
506 .cmp(&ONE.inv_sign())
507 .unwrap()
508 == 0
509 );
510 assert!(n.pow(&MAX).is_inf_neg());
511 assert!(n.pow(&MIN).is_zero());
512 assert!(n.pow(&ONE).cmp(&TWO.inv_sign()).unwrap() == 0);
513 assert!(n.pow(&TWO).is_positive());
514 assert!(n.pow(&ZERO).cmp(&ONE).unwrap() == 0);
515
516 let n = ONE.div(&TWO).inv_sign();
518 assert!(n.pow(&MIN_POSITIVE).cmp(&ONE.inv_sign()).unwrap() == 0);
519 assert!(
520 n.pow(&MIN_POSITIVE.inv_sign())
521 .cmp(&ONE.inv_sign())
522 .unwrap()
523 == 0
524 );
525 assert!(n.pow(&MAX).is_zero());
526 assert!(n.pow(&MIN).is_inf_neg());
527 assert!(n.pow(&ONE).cmp(&n).unwrap() == 0);
528 assert!(n.pow(&TWO).is_positive());
529 assert!(n.pow(&ZERO).cmp(&ONE).unwrap() == 0);
530
531 assert!(MAX.pow(&MIN_POSITIVE).cmp(&ONE).unwrap() == 0);
533 assert!(MAX.pow(&MIN_POSITIVE.inv_sign()).cmp(&ONE).unwrap() == 0);
534 assert!(MAX.pow(&MAX).is_inf_pos());
535 assert!(MAX.pow(&MIN).is_zero());
536 assert!(MAX.pow(&ONE).cmp(&MAX).unwrap() == 0);
537 assert!(MAX.pow(&ZERO).cmp(&ONE).unwrap() == 0);
538
539 assert!(MIN.pow(&MIN_POSITIVE).cmp(&ONE.inv_sign()).unwrap() == 0);
541 assert!(
542 MIN.pow(&MIN_POSITIVE.inv_sign())
543 .cmp(&ONE.inv_sign())
544 .unwrap()
545 == 0
546 );
547 assert!(MIN.pow(&MAX).is_inf_neg());
548 assert!(MIN.pow(&MIN).is_zero());
549 assert!(MIN.pow(&ONE).cmp(&MIN).unwrap() == 0);
550 assert!(MIN.pow(&ZERO).cmp(&ONE).unwrap() == 0);
551
552 assert!(MIN_POSITIVE.pow(&MIN_POSITIVE).cmp(&ONE).unwrap() == 0);
554 assert!(
555 MIN_POSITIVE
556 .pow(&MIN_POSITIVE.inv_sign())
557 .cmp(&ONE)
558 .unwrap()
559 == 0
560 );
561 assert!(MIN_POSITIVE.pow(&MAX).is_zero());
562 assert!(MIN_POSITIVE.pow(&MIN).is_inf_pos());
563 assert!(MIN_POSITIVE.pow(&ONE).cmp(&MIN_POSITIVE).unwrap() == 0);
564 assert!(MIN_POSITIVE.pow(&ZERO).cmp(&ONE).unwrap() == 0);
565
566 let n = MIN_POSITIVE.inv_sign();
568 assert!(n.pow(&MIN_POSITIVE).cmp(&ONE.inv_sign()).unwrap() == 0);
569 assert!(
570 n.pow(&MIN_POSITIVE.inv_sign())
571 .cmp(&ONE.inv_sign())
572 .unwrap()
573 == 0
574 );
575 assert!(n.pow(&MAX).is_zero());
576 assert!(n.pow(&MIN).is_inf_neg());
577 assert!(n.pow(&ONE).cmp(&n).unwrap() == 0);
578 assert!(n.pow(&TWO).is_positive());
579 assert!(n.pow(&ZERO).cmp(&ONE).unwrap() == 0);
580 }
581
582 #[test]
583 fn test_lib_ln_log2_log10() {
584 let ten = BigFloat::from_u8(10);
586 for _ in 0..10000 {
587 let num = random_normal_float(256, 127).abs();
588 if num.is_zero() {
589 assert!(num.ln().is_nan());
590 assert!(num.log2().is_nan());
591 assert!(num.log10().is_nan());
592 } else {
593 let l = num.ln();
594 let e = l.exp();
595 assert_small(&num.sub(&e), 4, &num);
596
597 let l = num.log2();
598 let e = TWO.pow(&l);
599 assert_small(&num.sub(&e), 4, &num);
600
601 let l = num.log10();
602 let e = ten.pow(&l);
603 assert_small(&num.sub(&e), 5, &num);
604 }
605 }
606
607 let ops = [BigFloat::ln, BigFloat::log2, BigFloat::log10];
608 let bases = [crate::E, TWO, ten];
609 for i in 0..ops.len() {
610 let op = ops[i];
611 let base = bases[i];
612
613 let n = op(&ONE);
615 assert_small_if_not(n.is_zero(), &ZERO.sub(&n), 2, &n);
616
617 let n = op(&MAX);
619 assert!(n.cmp(&ZERO).unwrap() > 0 && MAX.cmp(&n).unwrap() > 0);
620 let n = base.pow(&n);
621 assert_small_if_not(n.is_inf_pos(), &MAX.sub(&n), 4, &MAX);
622
623 let n = op(&MIN_POSITIVE);
625 assert!(n.cmp(&ZERO).unwrap() < 0 && MIN_POSITIVE.cmp(&n.abs()).unwrap() < 0);
626 let n = base.pow(&n);
627 assert_small_if_not(n.is_inf_neg(), &MIN_POSITIVE.sub(&n), 2, &n);
628
629 let n = op(&MIN_POSITIVE.inv_sign());
631 assert!(n.is_nan());
632
633 let n = op(&ZERO.inv_sign());
635 assert!(n.is_nan());
636 }
637 }
638
639 #[test]
640 fn test_lib_log() {
641 for _ in 0..10000 {
643 let base = random_normal_float(256, 127).abs();
644 let num = random_normal_float(256, 127).abs();
645 if num.is_zero() || base.is_zero() {
646 assert!(num.log(&base).is_nan());
647 } else {
648 let l = num.log(&base);
649 let e = base.pow(&l);
650 assert_small(&num.sub(&e), 5, &num);
651 }
652 }
653
654 let base1 = BigFloat::from_f64(5.4321);
656 let base2 = BigFloat::from_f64(0.4321);
657 let n = ONE.log(&base1);
658 assert_small_if_not(n.is_zero(), &ZERO.sub(&n), 2, &n);
659 let n = ONE.log(&base2);
660 assert_small_if_not(n.is_zero(), &ZERO.sub(&n), 2, &n);
661
662 let n = MAX.log(&base1);
664 assert!(n.cmp(&ZERO).unwrap() > 0 && MAX.cmp(&n).unwrap() > 0);
665 let n = base1.pow(&n);
666 assert_small_if_not(n.is_inf_pos(), &MAX.sub(&n), 4, &MAX);
667 let n = MAX.log(&base2);
668 assert!(n.cmp(&ZERO).unwrap() < 0 && MAX.cmp(&n.inv_sign()).unwrap() > 0);
669 let n = base2.pow(&n);
670 assert_small_if_not(n.is_inf_pos(), &MAX.sub(&n), 2, &MAX);
671
672 let n = MIN_POSITIVE.log(&base1);
674 assert!(n.cmp(&ZERO).unwrap() < 0 && MIN_POSITIVE.cmp(&n.abs()).unwrap() < 0);
675 let n = base1.pow(&n);
676 assert_small_if_not(n.is_inf_neg(), &MIN_POSITIVE.sub(&n), 2, &n);
677 let n = MIN_POSITIVE.log(&base2);
678 assert!(n.cmp(&ZERO).unwrap() > 0 && MIN_POSITIVE.cmp(&n.abs()).unwrap() < 0);
679 let n = base2.pow(&n);
680 assert_small_if_not(n.is_inf_neg(), &MIN_POSITIVE.sub(&n), 2, &n);
681
682 let n = MIN_POSITIVE.inv_sign().log(&base1);
684 assert!(n.is_nan());
685 let n = MIN_POSITIVE.inv_sign().log(&base2);
686 assert!(n.is_nan());
687
688 assert!(TWO.log(&base1.inv_sign()).is_nan());
690
691 let n = ZERO.inv_sign().log(&base1);
693 assert!(n.is_nan());
694 let n = ZERO.inv_sign().log(&base2);
695 assert!(n.is_nan());
696
697 assert!(TWO.log(&ZERO).is_nan());
699 }
700
701 #[test]
702 fn test_lib_sin_asin() {
703 let eps = BigFloat::from_f64(1.0e-7);
704 for _ in 0..10000 {
706 let num = random_normal_float(3, 40);
707 let s = num.sin();
708 let a = s.asin();
709 assert!(HALF_PI.cmp(&a).unwrap() >= 0 && HALF_PI.inv_sign().cmp(&a).unwrap() <= 0);
710 if ONE.sub(&s.abs()).cmp(&eps).unwrap() >= 0 {
711 if num.abs().cmp(&HALF_PI).unwrap() <= 0 {
715 assert_small(&num.sub(&a), 4, &num);
716 } else {
717 let mut sub1 = num.add(&a).abs().div(&PI).frac();
718 let mut sub2 = num.sub(&a).abs().div(&PI).frac();
719 if sub1.get_mantissa_len() > 3 {
720 sub1 = ONE.sub(&sub1);
721 }
722 if sub2.get_mantissa_len() > 3 {
723 sub2 = ONE.sub(&sub2);
724 }
725 assert_small_any(&sub1, &sub2, 3, &num);
726 }
727 }
728 }
729
730 let n = ZERO.sin();
732 assert!(n.is_zero() || ZERO.sub(&n).get_mantissa_len() < 2);
733
734 let n = PI.sin();
735 assert!(n.is_zero() || ZERO.sub(&n).get_exponent() < -(DECIMAL_POSITIONS as i8) - 38);
736
737 let n = PI.add(&PI).sin();
738 assert!(n.is_zero() || ZERO.sub(&n).get_exponent() < -(DECIMAL_POSITIONS as i8) - 38);
739
740 let n = MIN_POSITIVE.sin();
742 assert!(MIN_POSITIVE.sub(&n).get_mantissa_len() < 2);
743 let n = MIN_POSITIVE.inv_sign().sin();
744 assert!(MIN_POSITIVE.inv_sign().sub(&n).get_mantissa_len() < 2);
745
746 let eps = BigFloat::from_f64(1.0e-39);
748 let exp_err = -(DECIMAL_POSITIONS as i8) - 18;
749 test_extremum(BigFloat::sin, &HALF_PI, &ONE, 3, 2, 2, &eps, exp_err);
750 test_extremum(
751 BigFloat::sin,
752 &HALF_PI.add(&PI),
753 &ONE.inv_sign(),
754 3,
755 2,
756 2,
757 &eps,
758 exp_err,
759 );
760
761 test_extremum(BigFloat::asin, &ONE, &HALF_PI, 2, 2, 2, &eps, exp_err);
763 test_extremum(
764 BigFloat::asin,
765 &ONE.inv_sign(),
766 &HALF_PI.inv_sign(),
767 1,
768 2,
769 2,
770 &eps,
771 exp_err,
772 );
773
774 let n = MIN_POSITIVE.asin();
776 assert!(MIN_POSITIVE.sub(&n).get_mantissa_len() < 2);
777 let n = MIN_POSITIVE.inv_sign().asin();
778 assert!(MIN_POSITIVE.inv_sign().sub(&n).get_mantissa_len() < 2);
779
780 let n = TWO.asin();
782 assert!(n.is_nan());
783 let n = TWO.inv_sign().asin();
784 assert!(n.is_nan());
785 }
786
787 #[test]
788 fn test_lib_cos_acos() {
789 let eps = BigFloat::from_f64(1.0e-8);
790 for _ in 0..10000 {
791 let num = random_normal_float(3, 40);
792 let c = num.cos();
793 let a = c.acos();
794 assert!(PI.cmp(&a).unwrap() >= 0 && ZERO.inv_sign().cmp(&a).unwrap() <= 0);
795 if ONE.sub(&c.abs()).cmp(&eps).unwrap() >= 0 {
796 if num.abs().cmp(&PI).unwrap() <= 0 {
800 assert_small(&num.abs().sub(&a), 4, &num);
801 } else {
802 let mut sub1 = num.add(&a).abs().div(&PI).frac();
803 let mut sub2 = num.sub(&a).abs().div(&PI).frac();
804 if sub1.get_mantissa_len() > 3 {
805 sub1 = ONE.sub(&sub1);
806 }
807 if sub2.get_mantissa_len() > 3 {
808 sub2 = ONE.sub(&sub2);
809 }
810 assert_small_any(&sub1, &sub2, 3, &num);
811 }
812 }
813 }
814
815 let n = HALF_PI.cos();
817 assert!(n.is_zero() || ZERO.sub(&n).get_exponent() < -(DECIMAL_POSITIONS as i8) - 38);
818
819 let n = HALF_PI.add(&PI).cos();
820 assert!(n.is_zero() || ZERO.sub(&n).get_exponent() < -(DECIMAL_POSITIONS as i8) - 38);
821
822 let eps = BigFloat::from_f64(1.0e-39);
824 let exp_err = -(DECIMAL_POSITIONS as i8) - 18;
825 test_extremum(BigFloat::cos, &ZERO, &ONE, 3, 2, 2, &eps, exp_err);
826 test_extremum(BigFloat::cos, &PI, &ONE.inv_sign(), 3, 2, 2, &eps, exp_err);
827
828 test_extremum(BigFloat::acos, &ONE, &ZERO, 2, 2, 2, &eps, exp_err);
830 test_extremum(BigFloat::acos, &ONE.inv_sign(), &PI, 1, 2, 2, &eps, exp_err);
831
832 let n = TWO.acos();
834 assert!(n.is_nan());
835 let n = TWO.inv_sign().acos();
836 assert!(n.is_nan());
837 }
838
839 #[test]
840 fn test_lib_tan_atan() {
841 for _ in 0..10000 {
843 let num = random_normal_float(3, 40);
844 let t = num.tan();
845 let a = t.atan();
846 assert!(HALF_PI.cmp(&a).unwrap() >= 0 && HALF_PI.inv_sign().cmp(&a).unwrap() <= 0);
847 if num.abs().cmp(&HALF_PI).unwrap() <= 0 {
848 assert_small(&num.sub(&a), 2, &num);
849 } else {
850 let mut sub1 = num.add(&a).abs().div(&PI).frac();
851 let mut sub2 = num.sub(&a).abs().div(&PI).frac();
852 if sub1.get_mantissa_len() > 2 {
853 sub1 = ONE.sub(&sub1);
854 }
855 if sub2.get_mantissa_len() > 2 {
856 sub2 = ONE.sub(&sub2);
857 }
858 assert_small_any(&sub1, &sub2, 2, &num);
859 }
860 }
861
862 let eps = BigFloat::from_f64(1.0e-39);
864 let n = HALF_PI.tan();
865 assert!(n.get_mantissa_len() as i8 + n.get_exponent() > 39);
866 let n = HALF_PI.sub(&eps).tan();
867 assert!(n.get_mantissa_len() as i8 + n.get_exponent() > 39 && n.is_positive());
868 let n = HALF_PI.inv_sign().tan();
869 assert!(n.get_mantissa_len() as i8 + n.get_exponent() > 39);
870 let n = HALF_PI.sub(&eps).inv_sign().tan();
871 assert!(n.get_mantissa_len() as i8 + n.get_exponent() > 39 && n.is_negative());
872
873 let n = MAX.atan();
875 assert_small(&HALF_PI.sub(&n), 2, &HALF_PI);
876 let n = MIN.atan();
877 assert_small(&HALF_PI.inv_sign().sub(&n), 2, &HALF_PI.inv_sign());
878
879 let mut n = MAX;
880 n.set_exponent(n.get_exponent() - (DECIMAL_POSITIONS as i8));
881 let n = n.atan();
882 assert_small(&HALF_PI.sub(&n), 2, &HALF_PI);
883
884 let mut n = MIN;
885 n.set_exponent(n.get_exponent() - (DECIMAL_POSITIONS as i8));
886 let n = n.atan();
887 assert_small(&HALF_PI.inv_sign().sub(&n), 2, &HALF_PI.inv_sign());
888 }
889
890 #[test]
891 fn test_lib_sinh_asinh() {
892 for _ in 0..10000 {
894 let num = random_normal_float(91, 127);
895 let s = num.sinh();
896 let a = s.asinh();
897 if !a.is_inf() && !s.is_inf() {
898 assert_small(&num.sub(&a), 2, &num);
899 }
900 }
901
902 let n = MAX.sinh();
904 assert!(n.is_inf_pos());
905 let n = MIN.sinh();
906 assert!(n.is_inf_neg());
907
908 let n = MAX.asinh();
910 assert!(n.cmp(&MAX).unwrap() < 0);
911 let n = n.sinh();
912 assert_small_if_not(n.is_inf_pos(), &MAX.sub(&n), 2, &MAX);
913 let n = MIN.asinh();
914 assert!(n.cmp(&MIN).unwrap() > 0);
915 let n = n.sinh();
916 assert_small_if_not(n.is_inf_neg(), &MIN.sub(&n), 2, &MIN);
917 }
918
919 #[test]
920 fn test_lib_cosh_acosh() {
921 for _ in 0..10000 {
923 let num = random_normal_float(4, 40);
924 let s = num.cosh();
925 let a = s.acosh();
926 if !a.is_inf() && !s.is_inf() {
927 assert_small(&num.abs().sub(&a), 3, &num);
928 }
929 }
930
931 let exp_err = -(DECIMAL_POSITIONS as i8) - 37;
933 let eps = BigFloat::from_f64(1.0e-19);
934 test_extremum(BigFloat::cosh, &ZERO, &ONE, 3, 2, 2, &eps, exp_err);
935
936 let n = MAX.cosh();
938 assert!(n.is_inf_pos());
939 let n = MIN.cosh();
940 assert!(n.is_inf_pos());
941
942 let n = MAX.acosh();
944 assert!(n.cmp(&MAX).unwrap() < 0);
945 let n = n.cosh();
946 assert_small_if_not(n.is_inf_pos(), &MAX.sub(&n), 2, &MAX);
947
948 let exp_err = -(DECIMAL_POSITIONS as i8) - 18;
950 let eps = BigFloat::from_f64(1.0e-39);
951 test_extremum(BigFloat::acosh, &ONE, &ZERO, 1, 2, 2, &eps, exp_err);
952
953 let n = ZERO.acosh();
955 assert!(n.is_nan());
956 }
957
958 #[test]
959 fn test_lib_tanh_atanh() {
960 for _ in 0..10000 {
962 let num = random_normal_float(88, 127);
963 let s = num.tanh();
964 let a = s.atanh();
965 assert_small(&num.sub(&a), 2, &num);
966 }
967
968 let n = MAX.tanh();
970 assert!(n.cmp(&ONE).unwrap() == 0);
971 let n = MIN.tanh();
972 assert!(n.cmp(&ONE.inv_sign()).unwrap() == 0);
973
974 let n = ONE.atanh();
976 assert!(n.is_inf_pos());
977 let n = ONE.inv_sign().atanh();
978 assert!(n.is_inf_neg());
979
980 let n = MAX.atanh();
982 assert!(n.sub(&ZERO).get_mantissa_len() < 2);
983 let n = MIN.atanh();
984 assert!(n.sub(&ZERO).get_mantissa_len() < 2);
985
986 let n = TWO.atanh();
988 assert!(n.is_nan());
989 let n = TWO.inv_sign().atanh();
990 assert!(n.is_nan());
991 }
992
993 #[test]
994 fn test_lib_util() {
995 for _ in 0..1000 {
997 let num1 = random_normal_float(256, 127);
998 let num2 = random_normal_float(256, 127);
999 let n1 = num1.max(&num2);
1000 let n2 = num1.min(&num2);
1001 if num1.cmp(&num2).unwrap() > 0 {
1002 assert!(n1.cmp(&num1).unwrap() == 0);
1003 assert!(n2.cmp(&num2).unwrap() == 0);
1004 } else {
1005 assert!(n1.cmp(&num2).unwrap() == 0);
1006 assert!(n2.cmp(&num1).unwrap() == 0);
1007 }
1008 }
1009
1010 assert!(ONE.max(&INF_POS).cmp(&INF_POS).unwrap() == 0);
1011 assert!(INF_POS.max(&ONE).cmp(&INF_POS).unwrap() == 0);
1012 assert!(ONE.max(&INF_NEG).cmp(&ONE).unwrap() == 0);
1013 assert!(INF_NEG.max(&ONE).cmp(&ONE).unwrap() == 0);
1014 assert!(INF_POS.max(&INF_NEG).cmp(&INF_POS).unwrap() == 0);
1015 assert!(INF_NEG.max(&INF_POS).cmp(&INF_POS).unwrap() == 0);
1016 assert!(NAN.max(&ONE).is_nan());
1017 assert!(NAN.max(&NAN).is_nan());
1018 assert!(ONE.max(&NAN).is_nan());
1019 assert!(INF_POS.max(&NAN).is_nan());
1020 assert!(INF_NEG.max(&NAN).is_nan());
1021 assert!(NAN.max(&INF_POS).is_nan());
1022 assert!(NAN.max(&INF_NEG).is_nan());
1023
1024 assert!(ONE.min(&INF_POS).cmp(&ONE).unwrap() == 0);
1025 assert!(INF_POS.min(&ONE).cmp(&ONE).unwrap() == 0);
1026 assert!(ONE.min(&INF_NEG).cmp(&INF_NEG).unwrap() == 0);
1027 assert!(INF_NEG.min(&ONE).cmp(&INF_NEG).unwrap() == 0);
1028 assert!(INF_POS.min(&INF_NEG).cmp(&INF_NEG).unwrap() == 0);
1029 assert!(INF_NEG.min(&INF_POS).cmp(&INF_NEG).unwrap() == 0);
1030 assert!(NAN.min(&ONE).is_nan());
1031 assert!(NAN.min(&NAN).is_nan());
1032 assert!(ONE.min(&NAN).is_nan());
1033 assert!(INF_POS.min(&NAN).is_nan());
1034 assert!(INF_NEG.min(&NAN).is_nan());
1035 assert!(NAN.min(&INF_POS).is_nan());
1036 assert!(NAN.min(&INF_NEG).is_nan());
1037
1038 for _ in 0..1000 {
1040 let num1 = random_normal_float(256, 127);
1041 let num2 = random_normal_float(256, 127);
1042 let num3 = random_normal_float(256, 127);
1043 let upper = num1.max(&num2);
1044 let lower = num1.min(&num2);
1045 let n = num3.clamp(&lower, &upper);
1046 assert!(n.cmp(&upper).unwrap() <= 0);
1047 assert!(n.cmp(&lower).unwrap() >= 0);
1048 }
1049
1050 assert!(TWO.clamp(&ONE, &ONE).cmp(&ONE).unwrap() == 0);
1051 assert!(INF_POS.clamp(&ONE, &TWO).cmp(&TWO).unwrap() == 0);
1052 assert!(INF_NEG.clamp(&ONE, &TWO).cmp(&ONE).unwrap() == 0);
1053
1054 assert!(ONE.clamp(&INF_NEG, &INF_POS).cmp(&ONE).unwrap() == 0);
1055 assert!(INF_POS.clamp(&INF_NEG, &INF_POS).cmp(&INF_POS).unwrap() == 0);
1056 assert!(INF_NEG.clamp(&INF_NEG, &INF_POS).cmp(&INF_NEG).unwrap() == 0);
1057
1058 assert!(ONE.clamp(&TWO, &INF_POS).cmp(&TWO).unwrap() == 0);
1059 assert!(INF_POS.clamp(&TWO, &INF_POS).cmp(&INF_POS).unwrap() == 0);
1060 assert!(INF_NEG.clamp(&TWO, &INF_POS).cmp(&TWO).unwrap() == 0);
1061
1062 assert!(TWO.clamp(&INF_NEG, &ONE).cmp(&ONE).unwrap() == 0);
1063 assert!(INF_POS.clamp(&INF_NEG, &ONE).cmp(&ONE).unwrap() == 0);
1064 assert!(INF_NEG.clamp(&INF_NEG, &ONE).cmp(&INF_NEG).unwrap() == 0);
1065
1066 assert!(ZERO.clamp(&INF_POS, &INF_NEG).is_nan());
1067 assert!(ZERO.clamp(&TWO, &ONE).is_nan());
1068 assert!(ZERO.clamp(&INF_POS, &ONE).is_nan());
1069 assert!(ZERO.clamp(&TWO, &INF_NEG).is_nan());
1070
1071 for i in 1..0b111 {
1072 let n1 = if i & 1 == 0 { NAN } else { ONE };
1073 let n2 = if i & 0b10 == 0 { NAN } else { ONE };
1074 let n3 = if i & 0b100 == 0 { NAN } else { ONE };
1075 assert!(n1.clamp(&n2, &n3).is_nan());
1076 }
1077
1078 assert!(TWO.signum().cmp(&ONE).unwrap() == 0);
1080 assert!(ZERO.signum().cmp(&ONE).unwrap() == 0);
1081 assert!(TWO.inv_sign().signum().cmp(&ONE.inv_sign()).unwrap() == 0);
1082 assert!(NAN.signum().is_nan());
1083 assert!(INF_POS.signum().cmp(&ONE).unwrap() == 0);
1084 assert!(INF_NEG.signum().cmp(&ONE.inv_sign()).unwrap() == 0);
1085 }
1086
1087 #[test]
1088 fn test_lib_stable() {
1089 let mut d1: BigFloat;
1090 let mut d2: BigFloat;
1091 let niter = 10000;
1092
1093 for _ in 0..niter {
1094 d1 = random_normal_float(4, 30);
1095 d2 = random_normal_float(4, 34);
1096 check_stable1(
1097 BigFloat::add,
1098 BigFloat::sub,
1099 &d1,
1100 &d2,
1101 1,
1102 "check stable for add/sub",
1103 );
1104 }
1105
1106 for _ in 0..niter {
1107 d1 = random_normal_float(40, 40);
1108 d2 = random_normal_float(40, 40);
1109 check_stable1(
1110 BigFloat::mul,
1111 BigFloat::div,
1112 &d1,
1113 &d2,
1114 1,
1115 "check stable for mul/div",
1116 );
1117 }
1118
1119 for _ in 0..niter {
1120 d1 = random_normal_float(255, 127).abs();
1121 check_stable2(
1122 BigFloat::sqrt,
1123 |x| x.mul(x),
1124 &d1,
1125 5,
1126 "check stable for sqrt",
1127 );
1128 }
1129
1130 for _ in 0..niter {
1131 d1 = random_normal_float(255, 127).abs();
1132 check_stable2(
1133 BigFloat::cbrt,
1134 |x| x.mul(x).mul(x),
1135 &d1,
1136 5,
1137 "check stable for cbrt",
1138 );
1139 }
1140
1141 for _ in 0..niter {
1142 d1 = random_normal_float(255, 127).abs();
1143 check_stable2(
1144 BigFloat::ln,
1145 BigFloat::exp,
1146 &d1,
1147 5,
1148 "check stable for ln/exp",
1149 );
1150 }
1151
1152 for _ in 0..niter {
1153 d1 = random_normal_float(255, 127).abs();
1154 let d2 = random_normal_float(255, 127).abs();
1155 if !d1.is_zero() && !d1.is_zero() {
1156 check_stable1(
1157 BigFloat::log,
1158 |p1, p2| BigFloat::pow(p2, p1),
1159 &d1,
1160 &d2,
1161 1,
1162 "check stable for log/pow",
1163 );
1164 }
1165 }
1166
1167 for _ in 0..niter {
1168 d1 = random_normal_float(90, 127).abs();
1169 check_stable2(
1170 BigFloat::sin,
1171 BigFloat::asin,
1172 &d1,
1173 10,
1174 "check stable for sin/asin",
1175 );
1176 }
1177
1178 for _ in 0..niter {
1179 d1 = random_normal_float(90, 127).abs();
1180 check_stable2(
1181 BigFloat::cos,
1182 BigFloat::acos,
1183 &d1,
1184 10,
1185 "check stable for cos/acos",
1186 );
1187 }
1188
1189 for _ in 0..niter {
1190 d1 = random_normal_float(3, 40).abs();
1191 check_stable2(
1192 BigFloat::tan,
1193 BigFloat::atan,
1194 &d1,
1195 10,
1196 "check stable for tan/atan",
1197 );
1198 }
1199
1200 for _ in 0..niter {
1201 d1 = random_normal_float(91, 127);
1202 check_stable2(
1203 BigFloat::sinh,
1204 BigFloat::asinh,
1205 &d1,
1206 5,
1207 "check stable for sinh/asinh",
1208 );
1209 }
1210
1211 for _ in 0..niter {
1212 d1 = random_normal_float(91, 127);
1213 check_stable2(
1214 BigFloat::cosh,
1215 BigFloat::acosh,
1216 &d1,
1217 5,
1218 "check stable for cosh/acosh",
1219 );
1220 }
1221
1222 for _ in 0..niter {
1223 d1 = random_normal_float(88, 127);
1224 check_stable2(
1225 BigFloat::tanh,
1226 BigFloat::atanh,
1227 &d1,
1228 5,
1229 "check stable for tanh/atanh",
1230 );
1231 }
1232 }
1233
1234 fn random_f64_exp(exp_range: i32, exp_shift: i32) -> f64 {
1235 let mut f: f64 = random::<f64>() + 1.0;
1236 f *= 10.0f64.powi(random::<i32>().abs() % exp_range - exp_shift);
1237 if random::<i8>() & 1 == 0 {
1238 f = -f;
1239 }
1240 f
1241 }
1242
1243 fn random_normal_float(exp_range: i32, exp_shift: i32) -> BigFloat {
1244 let mut mantissa = [0i16; DECIMAL_PARTS];
1245 for i in 0..DECIMAL_PARTS {
1246 mantissa[i] = (random::<u16>() % DECIMAL_BASE as u16) as i16;
1247 }
1248 if mantissa[DECIMAL_PARTS - 1] == 0 {
1249 mantissa[DECIMAL_PARTS - 1] = (DECIMAL_BASE - 1) as i16;
1250 }
1251 while mantissa[DECIMAL_PARTS - 1] / 1000 == 0 {
1252 mantissa[DECIMAL_PARTS - 1] *= 10;
1253 }
1254 let sign = if random::<i8>() & 1 == 0 { DECIMAL_SIGN_POS } else { DECIMAL_SIGN_NEG };
1255 let exp = (if exp_range != 0 { random::<i32>().abs() % exp_range } else { 0 }) - exp_shift;
1256 BigFloat::from_raw_parts(mantissa, DECIMAL_POSITIONS as i16, sign, exp as i8)
1257 }
1258
1259 fn test_extremum(
1266 f: fn(&BigFloat) -> BigFloat,
1267 x: &BigFloat,
1268 y: &BigFloat,
1269 sides: u8,
1270 exact_err: usize,
1271 err: usize,
1272 eps: &BigFloat,
1273 exp_err: i8,
1274 ) {
1275 let n = f(x);
1276 assert_close(&n, y, exact_err, exp_err);
1277
1278 if sides & 1 != 0 {
1279 let x1 = x.add(eps);
1280 let n = f(&x1);
1281 assert_close(&n, y, err, exp_err);
1282 }
1283
1284 if sides & 2 != 0 {
1285 let x1 = x.sub(eps);
1286 let n = f(&x1);
1287 assert_close(&n, y, err, exp_err);
1288 }
1289 }
1290
1291 fn assert_close(n: &BigFloat, y: &BigFloat, err: usize, exp_err: i8) {
1293 assert!(
1294 n.cmp(y).unwrap() == 0
1295 || n.sub(y).get_mantissa_len() < err
1296 || n.sub(y).get_exponent() < exp_err
1297 );
1298 }
1299
1300 fn assert_small(v: &BigFloat, ndigits: i32, scale_num: &BigFloat) {
1302 let eps = get_assert_small_eps(ndigits, scale_num);
1303 assert!(v.abs().cmp(&eps).unwrap() < 0);
1304 }
1305
1306 fn assert_small_if_not(cond: bool, v: &BigFloat, ndigits: i32, scale_num: &BigFloat) {
1308 if !cond {
1309 assert_small(v, ndigits, scale_num);
1310 }
1311 }
1312
1313 fn assert_small_any(v1: &BigFloat, v2: &BigFloat, ndigits: i32, scale_num: &BigFloat) {
1315 let eps = get_assert_small_eps(ndigits, scale_num);
1316 assert!(v1.abs().cmp(&eps).unwrap() < 0 || v2.abs().cmp(&eps).unwrap() < 0);
1317 }
1318
1319 fn get_assert_small_eps(ndigits: i32, scale_num: &BigFloat) -> BigFloat {
1321 let mut eps = ONE;
1322 let e = ndigits - eps.get_mantissa_len() as i32 - (DECIMAL_POSITIONS as i32)
1323 + scale_num.get_exponent() as i32
1324 + scale_num.get_mantissa_len() as i32;
1325 if e < DECIMAL_MIN_EXPONENT as i32 {
1326 eps = MIN_POSITIVE;
1327 if e + DECIMAL_POSITIONS as i32 > DECIMAL_MIN_EXPONENT as i32 {
1328 eps.set_exponent((e + DECIMAL_POSITIONS as i32) as i8);
1329 }
1330 } else if e > DECIMAL_MAX_EXPONENT as i32 {
1331 eps = MAX;
1332 } else {
1333 eps.set_exponent(e as i8);
1334 }
1335 eps
1336 }
1337
1338 fn check_stable1(
1340 f: fn(&BigFloat, &BigFloat) -> BigFloat,
1341 finv: fn(&BigFloat, &BigFloat) -> BigFloat,
1342 d1: &BigFloat,
1343 d2: &BigFloat,
1344 niter: usize,
1345 #[allow(unused_variables)] msg: &str,
1346 ) {
1347 let mut n1 = *d1;
1348 let mut n2;
1349 for _ in 0..niter {
1350 let p = f(&n1, d2);
1351 n2 = finv(&p, d2);
1352 n1 = n2;
1353 }
1354 n2 = f(&n1, d2);
1355 n2 = finv(&n2, d2);
1356 let assertion = (n1.is_nan() && n2.is_nan()) || n1.cmp(&n2).unwrap() == 0;
1357 #[cfg(feature = "std")]
1358 if !assertion {
1359 println!("{}", msg);
1360 }
1361 assert!(assertion);
1362 }
1363
1364 fn check_stable2(
1366 f: fn(&BigFloat) -> BigFloat,
1367 finv: fn(&BigFloat) -> BigFloat,
1368 d1: &BigFloat,
1369 niter: usize,
1370 #[allow(unused_variables)] msg: &str,
1371 ) {
1372 let mut n1 = *d1;
1373 let mut n2;
1374 for _ in 0..niter {
1375 let p = f(&n1);
1376 n2 = finv(&p);
1377 n1 = n2;
1378 }
1379 n2 = f(&n1);
1380 n2 = finv(&n2);
1381 let assertion = (n1.is_nan() && n2.is_nan()) || n1.cmp(&n2).unwrap() == 0;
1382 #[cfg(feature = "std")]
1383 if !assertion {
1384 println!("{}", msg);
1385 }
1386 assert!(assertion);
1387 }
1388}