Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 12ad9b8

Browse files
committedMar 6, 2025·
Move float tests from std to core where applicable
A lot of float functionality lives in `core` but only gets tested in `std`. Split tests between `std` and `core` to reflect this and ensure as much as possible also can also get tested on no-std targets.
1 parent 056a40e commit 12ad9b8

File tree

12 files changed

+1187
-1137
lines changed

12 files changed

+1187
-1137
lines changed
 

‎library/coretests/build.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
mod build_shared {
2+
include!("../std/build_shared.rs");
3+
}
4+
5+
fn main() {
6+
let cfg = build_shared::Config::from_env();
7+
build_shared::configure_f16_f128(&cfg);
8+
}

‎library/coretests/tests/floats/f128.rs

Lines changed: 1 addition & 263 deletions
Original file line numberDiff line numberDiff line change
@@ -460,7 +460,7 @@ fn test_mul_add() {
460460
}
461461

462462
#[test]
463-
#[cfg(reliable_f16_math)]
463+
#[cfg(reliable_f128_math)]
464464
fn test_recip() {
465465
let nan: f128 = f128::NAN;
466466
let inf: f128 = f128::INFINITY;
@@ -479,8 +479,6 @@ fn test_recip() {
479479
assert_eq!(neg_inf.recip(), 0.0);
480480
}
481481

482-
// Many math functions allow for less accurate results, so the next tolerance up is used
483-
484482
#[test]
485483
#[cfg(reliable_f128_math)]
486484
fn test_powi() {
@@ -496,23 +494,6 @@ fn test_powi() {
496494
assert_eq!(neg_inf.powi(2), inf);
497495
}
498496

499-
#[test]
500-
#[cfg(reliable_f128_math)]
501-
fn test_powf() {
502-
let nan: f128 = f128::NAN;
503-
let inf: f128 = f128::INFINITY;
504-
let neg_inf: f128 = f128::NEG_INFINITY;
505-
assert_eq!(1.0f128.powf(1.0), 1.0);
506-
assert_approx_eq!(3.4f128.powf(4.5), 246.40818323761892815995637964326426756, TOL_IMPR);
507-
assert_approx_eq!(2.7f128.powf(-3.2), 0.041652009108526178281070304373500889273, TOL_IMPR);
508-
assert_approx_eq!((-3.1f128).powf(2.0), 9.6100000000000005506706202140776519387, TOL_IMPR);
509-
assert_approx_eq!(5.9f128.powf(-2.0), 0.028727377190462507313100483690639638451, TOL_IMPR);
510-
assert_eq!(8.3f128.powf(0.0), 1.0);
511-
assert!(nan.powf(2.0).is_nan());
512-
assert_eq!(inf.powf(2.0), inf);
513-
assert_eq!(neg_inf.powf(3.0), neg_inf);
514-
}
515-
516497
#[test]
517498
#[cfg(reliable_f128_math)]
518499
fn test_sqrt_domain() {
@@ -525,105 +506,6 @@ fn test_sqrt_domain() {
525506
assert_eq!(f128::INFINITY.sqrt(), f128::INFINITY);
526507
}
527508

528-
#[test]
529-
#[cfg(reliable_f128_math)]
530-
fn test_exp() {
531-
assert_eq!(1.0, 0.0f128.exp());
532-
assert_approx_eq!(consts::E, 1.0f128.exp(), TOL);
533-
assert_approx_eq!(148.41315910257660342111558004055227962348775, 5.0f128.exp(), TOL);
534-
535-
let inf: f128 = f128::INFINITY;
536-
let neg_inf: f128 = f128::NEG_INFINITY;
537-
let nan: f128 = f128::NAN;
538-
assert_eq!(inf, inf.exp());
539-
assert_eq!(0.0, neg_inf.exp());
540-
assert!(nan.exp().is_nan());
541-
}
542-
543-
#[test]
544-
#[cfg(reliable_f128_math)]
545-
fn test_exp2() {
546-
assert_eq!(32.0, 5.0f128.exp2());
547-
assert_eq!(1.0, 0.0f128.exp2());
548-
549-
let inf: f128 = f128::INFINITY;
550-
let neg_inf: f128 = f128::NEG_INFINITY;
551-
let nan: f128 = f128::NAN;
552-
assert_eq!(inf, inf.exp2());
553-
assert_eq!(0.0, neg_inf.exp2());
554-
assert!(nan.exp2().is_nan());
555-
}
556-
557-
#[test]
558-
#[cfg(reliable_f128_math)]
559-
fn test_ln() {
560-
let nan: f128 = f128::NAN;
561-
let inf: f128 = f128::INFINITY;
562-
let neg_inf: f128 = f128::NEG_INFINITY;
563-
assert_approx_eq!(1.0f128.exp().ln(), 1.0, TOL);
564-
assert!(nan.ln().is_nan());
565-
assert_eq!(inf.ln(), inf);
566-
assert!(neg_inf.ln().is_nan());
567-
assert!((-2.3f128).ln().is_nan());
568-
assert_eq!((-0.0f128).ln(), neg_inf);
569-
assert_eq!(0.0f128.ln(), neg_inf);
570-
assert_approx_eq!(4.0f128.ln(), 1.3862943611198906188344642429163531366, TOL);
571-
}
572-
573-
#[test]
574-
#[cfg(reliable_f128_math)]
575-
fn test_log() {
576-
let nan: f128 = f128::NAN;
577-
let inf: f128 = f128::INFINITY;
578-
let neg_inf: f128 = f128::NEG_INFINITY;
579-
assert_eq!(10.0f128.log(10.0), 1.0);
580-
assert_approx_eq!(2.3f128.log(3.5), 0.66485771361478710036766645911922010272, TOL);
581-
assert_eq!(1.0f128.exp().log(1.0f128.exp()), 1.0);
582-
assert!(1.0f128.log(1.0).is_nan());
583-
assert!(1.0f128.log(-13.9).is_nan());
584-
assert!(nan.log(2.3).is_nan());
585-
assert_eq!(inf.log(10.0), inf);
586-
assert!(neg_inf.log(8.8).is_nan());
587-
assert!((-2.3f128).log(0.1).is_nan());
588-
assert_eq!((-0.0f128).log(2.0), neg_inf);
589-
assert_eq!(0.0f128.log(7.0), neg_inf);
590-
}
591-
592-
#[test]
593-
#[cfg(reliable_f128_math)]
594-
fn test_log2() {
595-
let nan: f128 = f128::NAN;
596-
let inf: f128 = f128::INFINITY;
597-
let neg_inf: f128 = f128::NEG_INFINITY;
598-
assert_approx_eq!(10.0f128.log2(), 3.32192809488736234787031942948939017, TOL);
599-
assert_approx_eq!(2.3f128.log2(), 1.2016338611696504130002982471978765921, TOL);
600-
assert_approx_eq!(1.0f128.exp().log2(), 1.4426950408889634073599246810018921381, TOL);
601-
assert!(nan.log2().is_nan());
602-
assert_eq!(inf.log2(), inf);
603-
assert!(neg_inf.log2().is_nan());
604-
assert!((-2.3f128).log2().is_nan());
605-
assert_eq!((-0.0f128).log2(), neg_inf);
606-
assert_eq!(0.0f128.log2(), neg_inf);
607-
}
608-
609-
#[test]
610-
#[cfg(reliable_f128_math)]
611-
fn test_log10() {
612-
let nan: f128 = f128::NAN;
613-
let inf: f128 = f128::INFINITY;
614-
let neg_inf: f128 = f128::NEG_INFINITY;
615-
assert_eq!(10.0f128.log10(), 1.0);
616-
assert_approx_eq!(2.3f128.log10(), 0.36172783601759284532595218865859309898, TOL);
617-
assert_approx_eq!(1.0f128.exp().log10(), 0.43429448190325182765112891891660508222, TOL);
618-
assert_eq!(1.0f128.log10(), 0.0);
619-
assert!(nan.log10().is_nan());
620-
assert_eq!(inf.log10(), inf);
621-
assert!(neg_inf.log10().is_nan());
622-
assert!((-2.3f128).log10().is_nan());
623-
assert_eq!((-0.0f128).log10(), neg_inf);
624-
assert_eq!(0.0f128.log10(), neg_inf);
625-
}
626-
627509
#[test]
628510
fn test_to_degrees() {
629511
let pi: f128 = consts::PI;
@@ -656,150 +538,6 @@ fn test_to_radians() {
656538
assert_eq!(neg_inf.to_radians(), neg_inf);
657539
}
658540

659-
#[test]
660-
#[cfg(reliable_f128_math)]
661-
fn test_asinh() {
662-
// Lower accuracy results are allowed, use increased tolerances
663-
assert_eq!(0.0f128.asinh(), 0.0f128);
664-
assert_eq!((-0.0f128).asinh(), -0.0f128);
665-
666-
let inf: f128 = f128::INFINITY;
667-
let neg_inf: f128 = f128::NEG_INFINITY;
668-
let nan: f128 = f128::NAN;
669-
assert_eq!(inf.asinh(), inf);
670-
assert_eq!(neg_inf.asinh(), neg_inf);
671-
assert!(nan.asinh().is_nan());
672-
assert!((-0.0f128).asinh().is_sign_negative());
673-
674-
// issue 63271
675-
assert_approx_eq!(2.0f128.asinh(), 1.443635475178810342493276740273105f128, TOL_IMPR);
676-
assert_approx_eq!((-2.0f128).asinh(), -1.443635475178810342493276740273105f128, TOL_IMPR);
677-
// regression test for the catastrophic cancellation fixed in 72486
678-
assert_approx_eq!(
679-
(-67452098.07139316f128).asinh(),
680-
-18.720075426274544393985484294000831757220,
681-
TOL_IMPR
682-
);
683-
684-
// test for low accuracy from issue 104548
685-
assert_approx_eq!(60.0f128, 60.0f128.sinh().asinh(), TOL_IMPR);
686-
// mul needed for approximate comparison to be meaningful
687-
assert_approx_eq!(1.0f128, 1e-15f128.sinh().asinh() * 1e15f128, TOL_IMPR);
688-
}
689-
690-
#[test]
691-
#[cfg(reliable_f128_math)]
692-
fn test_acosh() {
693-
assert_eq!(1.0f128.acosh(), 0.0f128);
694-
assert!(0.999f128.acosh().is_nan());
695-
696-
let inf: f128 = f128::INFINITY;
697-
let neg_inf: f128 = f128::NEG_INFINITY;
698-
let nan: f128 = f128::NAN;
699-
assert_eq!(inf.acosh(), inf);
700-
assert!(neg_inf.acosh().is_nan());
701-
assert!(nan.acosh().is_nan());
702-
assert_approx_eq!(2.0f128.acosh(), 1.31695789692481670862504634730796844f128, TOL_IMPR);
703-
assert_approx_eq!(3.0f128.acosh(), 1.76274717403908605046521864995958461f128, TOL_IMPR);
704-
705-
// test for low accuracy from issue 104548
706-
assert_approx_eq!(60.0f128, 60.0f128.cosh().acosh(), TOL_IMPR);
707-
}
708-
709-
#[test]
710-
#[cfg(reliable_f128_math)]
711-
fn test_atanh() {
712-
assert_eq!(0.0f128.atanh(), 0.0f128);
713-
assert_eq!((-0.0f128).atanh(), -0.0f128);
714-
715-
let inf: f128 = f128::INFINITY;
716-
let neg_inf: f128 = f128::NEG_INFINITY;
717-
let nan: f128 = f128::NAN;
718-
assert_eq!(1.0f128.atanh(), inf);
719-
assert_eq!((-1.0f128).atanh(), neg_inf);
720-
assert!(2f128.atanh().atanh().is_nan());
721-
assert!((-2f128).atanh().atanh().is_nan());
722-
assert!(inf.atanh().is_nan());
723-
assert!(neg_inf.atanh().is_nan());
724-
assert!(nan.atanh().is_nan());
725-
assert_approx_eq!(0.5f128.atanh(), 0.54930614433405484569762261846126285f128, TOL_IMPR);
726-
assert_approx_eq!((-0.5f128).atanh(), -0.54930614433405484569762261846126285f128, TOL_IMPR);
727-
}
728-
729-
#[test]
730-
#[cfg(reliable_f128_math)]
731-
fn test_gamma() {
732-
// precision can differ among platforms
733-
assert_approx_eq!(1.0f128.gamma(), 1.0f128, TOL_IMPR);
734-
assert_approx_eq!(2.0f128.gamma(), 1.0f128, TOL_IMPR);
735-
assert_approx_eq!(3.0f128.gamma(), 2.0f128, TOL_IMPR);
736-
assert_approx_eq!(4.0f128.gamma(), 6.0f128, TOL_IMPR);
737-
assert_approx_eq!(5.0f128.gamma(), 24.0f128, TOL_IMPR);
738-
assert_approx_eq!(0.5f128.gamma(), consts::PI.sqrt(), TOL_IMPR);
739-
assert_approx_eq!((-0.5f128).gamma(), -2.0 * consts::PI.sqrt(), TOL_IMPR);
740-
assert_eq!(0.0f128.gamma(), f128::INFINITY);
741-
assert_eq!((-0.0f128).gamma(), f128::NEG_INFINITY);
742-
assert!((-1.0f128).gamma().is_nan());
743-
assert!((-2.0f128).gamma().is_nan());
744-
assert!(f128::NAN.gamma().is_nan());
745-
assert!(f128::NEG_INFINITY.gamma().is_nan());
746-
assert_eq!(f128::INFINITY.gamma(), f128::INFINITY);
747-
assert_eq!(1760.9f128.gamma(), f128::INFINITY);
748-
}
749-
750-
#[test]
751-
#[cfg(reliable_f128_math)]
752-
fn test_ln_gamma() {
753-
assert_approx_eq!(1.0f128.ln_gamma().0, 0.0f128, TOL_IMPR);
754-
assert_eq!(1.0f128.ln_gamma().1, 1);
755-
assert_approx_eq!(2.0f128.ln_gamma().0, 0.0f128, TOL_IMPR);
756-
assert_eq!(2.0f128.ln_gamma().1, 1);
757-
assert_approx_eq!(3.0f128.ln_gamma().0, 2.0f128.ln(), TOL_IMPR);
758-
assert_eq!(3.0f128.ln_gamma().1, 1);
759-
assert_approx_eq!((-0.5f128).ln_gamma().0, (2.0 * consts::PI.sqrt()).ln(), TOL_IMPR);
760-
assert_eq!((-0.5f128).ln_gamma().1, -1);
761-
}
762-
763-
#[test]
764-
fn test_real_consts() {
765-
let pi: f128 = consts::PI;
766-
let frac_pi_2: f128 = consts::FRAC_PI_2;
767-
let frac_pi_3: f128 = consts::FRAC_PI_3;
768-
let frac_pi_4: f128 = consts::FRAC_PI_4;
769-
let frac_pi_6: f128 = consts::FRAC_PI_6;
770-
let frac_pi_8: f128 = consts::FRAC_PI_8;
771-
let frac_1_pi: f128 = consts::FRAC_1_PI;
772-
let frac_2_pi: f128 = consts::FRAC_2_PI;
773-
774-
assert_approx_eq!(frac_pi_2, pi / 2f128, TOL_PRECISE);
775-
assert_approx_eq!(frac_pi_3, pi / 3f128, TOL_PRECISE);
776-
assert_approx_eq!(frac_pi_4, pi / 4f128, TOL_PRECISE);
777-
assert_approx_eq!(frac_pi_6, pi / 6f128, TOL_PRECISE);
778-
assert_approx_eq!(frac_pi_8, pi / 8f128, TOL_PRECISE);
779-
assert_approx_eq!(frac_1_pi, 1f128 / pi, TOL_PRECISE);
780-
assert_approx_eq!(frac_2_pi, 2f128 / pi, TOL_PRECISE);
781-
782-
#[cfg(reliable_f128_math)]
783-
{
784-
let frac_2_sqrtpi: f128 = consts::FRAC_2_SQRT_PI;
785-
let sqrt2: f128 = consts::SQRT_2;
786-
let frac_1_sqrt2: f128 = consts::FRAC_1_SQRT_2;
787-
let e: f128 = consts::E;
788-
let log2_e: f128 = consts::LOG2_E;
789-
let log10_e: f128 = consts::LOG10_E;
790-
let ln_2: f128 = consts::LN_2;
791-
let ln_10: f128 = consts::LN_10;
792-
793-
assert_approx_eq!(frac_2_sqrtpi, 2f128 / pi.sqrt(), TOL_PRECISE);
794-
assert_approx_eq!(sqrt2, 2f128.sqrt(), TOL_PRECISE);
795-
assert_approx_eq!(frac_1_sqrt2, 1f128 / 2f128.sqrt(), TOL_PRECISE);
796-
assert_approx_eq!(log2_e, e.log2(), TOL_PRECISE);
797-
assert_approx_eq!(log10_e, e.log10(), TOL_PRECISE);
798-
assert_approx_eq!(ln_2, 2f128.ln(), TOL_PRECISE);
799-
assert_approx_eq!(ln_10, 10f128.ln(), TOL_PRECISE);
800-
}
801-
}
802-
803541
#[test]
804542
fn test_float_bits_conv() {
805543
assert_eq!((1f128).to_bits(), 0x3fff0000000000000000000000000000);

‎library/coretests/tests/floats/f16.rs

Lines changed: 1 addition & 257 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ macro_rules! assert_f16_biteq {
5454

5555
#[test]
5656
fn test_num_f16() {
57-
crate::test_num(10f16, 2f16);
57+
super::test_num(10f16, 2f16);
5858
}
5959

6060
#[test]
@@ -475,23 +475,6 @@ fn test_powi() {
475475
// assert_eq!(neg_inf.powi(2), inf);
476476
}
477477

478-
#[test]
479-
#[cfg(reliable_f16_math)]
480-
fn test_powf() {
481-
let nan: f16 = f16::NAN;
482-
let inf: f16 = f16::INFINITY;
483-
let neg_inf: f16 = f16::NEG_INFINITY;
484-
assert_eq!(1.0f16.powf(1.0), 1.0);
485-
assert_approx_eq!(3.4f16.powf(4.5), 246.408183, TOL_P2);
486-
assert_approx_eq!(2.7f16.powf(-3.2), 0.041652, TOL_N2);
487-
assert_approx_eq!((-3.1f16).powf(2.0), 9.61, TOL_P2);
488-
assert_approx_eq!(5.9f16.powf(-2.0), 0.028727, TOL_N2);
489-
assert_eq!(8.3f16.powf(0.0), 1.0);
490-
assert!(nan.powf(2.0).is_nan());
491-
assert_eq!(inf.powf(2.0), inf);
492-
assert_eq!(neg_inf.powf(3.0), neg_inf);
493-
}
494-
495478
#[test]
496479
#[cfg(reliable_f16_math)]
497480
fn test_sqrt_domain() {
@@ -504,105 +487,6 @@ fn test_sqrt_domain() {
504487
assert_eq!(f16::INFINITY.sqrt(), f16::INFINITY);
505488
}
506489

507-
#[test]
508-
#[cfg(reliable_f16_math)]
509-
fn test_exp() {
510-
assert_eq!(1.0, 0.0f16.exp());
511-
assert_approx_eq!(2.718282, 1.0f16.exp(), TOL_0);
512-
assert_approx_eq!(148.413159, 5.0f16.exp(), TOL_0);
513-
514-
let inf: f16 = f16::INFINITY;
515-
let neg_inf: f16 = f16::NEG_INFINITY;
516-
let nan: f16 = f16::NAN;
517-
assert_eq!(inf, inf.exp());
518-
assert_eq!(0.0, neg_inf.exp());
519-
assert!(nan.exp().is_nan());
520-
}
521-
522-
#[test]
523-
#[cfg(reliable_f16_math)]
524-
fn test_exp2() {
525-
assert_eq!(32.0, 5.0f16.exp2());
526-
assert_eq!(1.0, 0.0f16.exp2());
527-
528-
let inf: f16 = f16::INFINITY;
529-
let neg_inf: f16 = f16::NEG_INFINITY;
530-
let nan: f16 = f16::NAN;
531-
assert_eq!(inf, inf.exp2());
532-
assert_eq!(0.0, neg_inf.exp2());
533-
assert!(nan.exp2().is_nan());
534-
}
535-
536-
#[test]
537-
#[cfg(reliable_f16_math)]
538-
fn test_ln() {
539-
let nan: f16 = f16::NAN;
540-
let inf: f16 = f16::INFINITY;
541-
let neg_inf: f16 = f16::NEG_INFINITY;
542-
assert_approx_eq!(1.0f16.exp().ln(), 1.0, TOL_0);
543-
assert!(nan.ln().is_nan());
544-
assert_eq!(inf.ln(), inf);
545-
assert!(neg_inf.ln().is_nan());
546-
assert!((-2.3f16).ln().is_nan());
547-
assert_eq!((-0.0f16).ln(), neg_inf);
548-
assert_eq!(0.0f16.ln(), neg_inf);
549-
assert_approx_eq!(4.0f16.ln(), 1.386294, TOL_0);
550-
}
551-
552-
#[test]
553-
#[cfg(reliable_f16_math)]
554-
fn test_log() {
555-
let nan: f16 = f16::NAN;
556-
let inf: f16 = f16::INFINITY;
557-
let neg_inf: f16 = f16::NEG_INFINITY;
558-
assert_eq!(10.0f16.log(10.0), 1.0);
559-
assert_approx_eq!(2.3f16.log(3.5), 0.664858, TOL_0);
560-
assert_eq!(1.0f16.exp().log(1.0f16.exp()), 1.0);
561-
assert!(1.0f16.log(1.0).is_nan());
562-
assert!(1.0f16.log(-13.9).is_nan());
563-
assert!(nan.log(2.3).is_nan());
564-
assert_eq!(inf.log(10.0), inf);
565-
assert!(neg_inf.log(8.8).is_nan());
566-
assert!((-2.3f16).log(0.1).is_nan());
567-
assert_eq!((-0.0f16).log(2.0), neg_inf);
568-
assert_eq!(0.0f16.log(7.0), neg_inf);
569-
}
570-
571-
#[test]
572-
#[cfg(reliable_f16_math)]
573-
fn test_log2() {
574-
let nan: f16 = f16::NAN;
575-
let inf: f16 = f16::INFINITY;
576-
let neg_inf: f16 = f16::NEG_INFINITY;
577-
assert_approx_eq!(10.0f16.log2(), 3.321928, TOL_0);
578-
assert_approx_eq!(2.3f16.log2(), 1.201634, TOL_0);
579-
assert_approx_eq!(1.0f16.exp().log2(), 1.442695, TOL_0);
580-
assert!(nan.log2().is_nan());
581-
assert_eq!(inf.log2(), inf);
582-
assert!(neg_inf.log2().is_nan());
583-
assert!((-2.3f16).log2().is_nan());
584-
assert_eq!((-0.0f16).log2(), neg_inf);
585-
assert_eq!(0.0f16.log2(), neg_inf);
586-
}
587-
588-
#[test]
589-
#[cfg(reliable_f16_math)]
590-
fn test_log10() {
591-
let nan: f16 = f16::NAN;
592-
let inf: f16 = f16::INFINITY;
593-
let neg_inf: f16 = f16::NEG_INFINITY;
594-
assert_eq!(10.0f16.log10(), 1.0);
595-
assert_approx_eq!(2.3f16.log10(), 0.361728, TOL_0);
596-
assert_approx_eq!(1.0f16.exp().log10(), 0.434294, TOL_0);
597-
assert_eq!(1.0f16.log10(), 0.0);
598-
assert!(nan.log10().is_nan());
599-
assert_eq!(inf.log10(), inf);
600-
assert!(neg_inf.log10().is_nan());
601-
assert!((-2.3f16).log10().is_nan());
602-
assert_eq!((-0.0f16).log10(), neg_inf);
603-
assert_eq!(0.0f16.log10(), neg_inf);
604-
}
605-
606490
#[test]
607491
fn test_to_degrees() {
608492
let pi: f16 = consts::PI;
@@ -633,146 +517,6 @@ fn test_to_radians() {
633517
assert_eq!(neg_inf.to_radians(), neg_inf);
634518
}
635519

636-
#[test]
637-
#[cfg(reliable_f16_math)]
638-
fn test_asinh() {
639-
assert_eq!(0.0f16.asinh(), 0.0f16);
640-
assert_eq!((-0.0f16).asinh(), -0.0f16);
641-
642-
let inf: f16 = f16::INFINITY;
643-
let neg_inf: f16 = f16::NEG_INFINITY;
644-
let nan: f16 = f16::NAN;
645-
assert_eq!(inf.asinh(), inf);
646-
assert_eq!(neg_inf.asinh(), neg_inf);
647-
assert!(nan.asinh().is_nan());
648-
assert!((-0.0f16).asinh().is_sign_negative());
649-
// issue 63271
650-
assert_approx_eq!(2.0f16.asinh(), 1.443635475178810342493276740273105f16, TOL_0);
651-
assert_approx_eq!((-2.0f16).asinh(), -1.443635475178810342493276740273105f16, TOL_0);
652-
// regression test for the catastrophic cancellation fixed in 72486
653-
assert_approx_eq!((-200.0f16).asinh(), -5.991470797049389, TOL_0);
654-
655-
// test for low accuracy from issue 104548
656-
assert_approx_eq!(10.0f16, 10.0f16.sinh().asinh(), TOL_0);
657-
// mul needed for approximate comparison to be meaningful
658-
assert_approx_eq!(1.0f16, 1e-3f16.sinh().asinh() * 1e3f16, TOL_0);
659-
}
660-
661-
#[test]
662-
#[cfg(reliable_f16_math)]
663-
fn test_acosh() {
664-
assert_eq!(1.0f16.acosh(), 0.0f16);
665-
assert!(0.999f16.acosh().is_nan());
666-
667-
let inf: f16 = f16::INFINITY;
668-
let neg_inf: f16 = f16::NEG_INFINITY;
669-
let nan: f16 = f16::NAN;
670-
assert_eq!(inf.acosh(), inf);
671-
assert!(neg_inf.acosh().is_nan());
672-
assert!(nan.acosh().is_nan());
673-
assert_approx_eq!(2.0f16.acosh(), 1.31695789692481670862504634730796844f16, TOL_0);
674-
assert_approx_eq!(3.0f16.acosh(), 1.76274717403908605046521864995958461f16, TOL_0);
675-
676-
// test for low accuracy from issue 104548
677-
assert_approx_eq!(10.0f16, 10.0f16.cosh().acosh(), TOL_P2);
678-
}
679-
680-
#[test]
681-
#[cfg(reliable_f16_math)]
682-
fn test_atanh() {
683-
assert_eq!(0.0f16.atanh(), 0.0f16);
684-
assert_eq!((-0.0f16).atanh(), -0.0f16);
685-
686-
let inf: f16 = f16::INFINITY;
687-
let neg_inf: f16 = f16::NEG_INFINITY;
688-
let nan: f16 = f16::NAN;
689-
assert_eq!(1.0f16.atanh(), inf);
690-
assert_eq!((-1.0f16).atanh(), neg_inf);
691-
assert!(2f16.atanh().atanh().is_nan());
692-
assert!((-2f16).atanh().atanh().is_nan());
693-
assert!(inf.atanh().is_nan());
694-
assert!(neg_inf.atanh().is_nan());
695-
assert!(nan.atanh().is_nan());
696-
assert_approx_eq!(0.5f16.atanh(), 0.54930614433405484569762261846126285f16, TOL_0);
697-
assert_approx_eq!((-0.5f16).atanh(), -0.54930614433405484569762261846126285f16, TOL_0);
698-
}
699-
700-
#[test]
701-
#[cfg(reliable_f16_math)]
702-
fn test_gamma() {
703-
// precision can differ among platforms
704-
assert_approx_eq!(1.0f16.gamma(), 1.0f16, TOL_0);
705-
assert_approx_eq!(2.0f16.gamma(), 1.0f16, TOL_0);
706-
assert_approx_eq!(3.0f16.gamma(), 2.0f16, TOL_0);
707-
assert_approx_eq!(4.0f16.gamma(), 6.0f16, TOL_0);
708-
assert_approx_eq!(5.0f16.gamma(), 24.0f16, TOL_0);
709-
assert_approx_eq!(0.5f16.gamma(), consts::PI.sqrt(), TOL_0);
710-
assert_approx_eq!((-0.5f16).gamma(), -2.0 * consts::PI.sqrt(), TOL_0);
711-
assert_eq!(0.0f16.gamma(), f16::INFINITY);
712-
assert_eq!((-0.0f16).gamma(), f16::NEG_INFINITY);
713-
assert!((-1.0f16).gamma().is_nan());
714-
assert!((-2.0f16).gamma().is_nan());
715-
assert!(f16::NAN.gamma().is_nan());
716-
assert!(f16::NEG_INFINITY.gamma().is_nan());
717-
assert_eq!(f16::INFINITY.gamma(), f16::INFINITY);
718-
assert_eq!(171.71f16.gamma(), f16::INFINITY);
719-
}
720-
721-
#[test]
722-
#[cfg(reliable_f16_math)]
723-
fn test_ln_gamma() {
724-
assert_approx_eq!(1.0f16.ln_gamma().0, 0.0f16, TOL_0);
725-
assert_eq!(1.0f16.ln_gamma().1, 1);
726-
assert_approx_eq!(2.0f16.ln_gamma().0, 0.0f16, TOL_0);
727-
assert_eq!(2.0f16.ln_gamma().1, 1);
728-
assert_approx_eq!(3.0f16.ln_gamma().0, 2.0f16.ln(), TOL_0);
729-
assert_eq!(3.0f16.ln_gamma().1, 1);
730-
assert_approx_eq!((-0.5f16).ln_gamma().0, (2.0 * consts::PI.sqrt()).ln(), TOL_0);
731-
assert_eq!((-0.5f16).ln_gamma().1, -1);
732-
}
733-
734-
#[test]
735-
fn test_real_consts() {
736-
// FIXME(f16_f128): add math tests when available
737-
738-
let pi: f16 = consts::PI;
739-
let frac_pi_2: f16 = consts::FRAC_PI_2;
740-
let frac_pi_3: f16 = consts::FRAC_PI_3;
741-
let frac_pi_4: f16 = consts::FRAC_PI_4;
742-
let frac_pi_6: f16 = consts::FRAC_PI_6;
743-
let frac_pi_8: f16 = consts::FRAC_PI_8;
744-
let frac_1_pi: f16 = consts::FRAC_1_PI;
745-
let frac_2_pi: f16 = consts::FRAC_2_PI;
746-
747-
assert_approx_eq!(frac_pi_2, pi / 2f16, TOL_0);
748-
assert_approx_eq!(frac_pi_3, pi / 3f16, TOL_0);
749-
assert_approx_eq!(frac_pi_4, pi / 4f16, TOL_0);
750-
assert_approx_eq!(frac_pi_6, pi / 6f16, TOL_0);
751-
assert_approx_eq!(frac_pi_8, pi / 8f16, TOL_0);
752-
assert_approx_eq!(frac_1_pi, 1f16 / pi, TOL_0);
753-
assert_approx_eq!(frac_2_pi, 2f16 / pi, TOL_0);
754-
755-
#[cfg(reliable_f16_math)]
756-
{
757-
let frac_2_sqrtpi: f16 = consts::FRAC_2_SQRT_PI;
758-
let sqrt2: f16 = consts::SQRT_2;
759-
let frac_1_sqrt2: f16 = consts::FRAC_1_SQRT_2;
760-
let e: f16 = consts::E;
761-
let log2_e: f16 = consts::LOG2_E;
762-
let log10_e: f16 = consts::LOG10_E;
763-
let ln_2: f16 = consts::LN_2;
764-
let ln_10: f16 = consts::LN_10;
765-
766-
assert_approx_eq!(frac_2_sqrtpi, 2f16 / pi.sqrt(), TOL_0);
767-
assert_approx_eq!(sqrt2, 2f16.sqrt(), TOL_0);
768-
assert_approx_eq!(frac_1_sqrt2, 1f16 / 2f16.sqrt(), TOL_0);
769-
assert_approx_eq!(log2_e, e.log2(), TOL_0);
770-
assert_approx_eq!(log10_e, e.log10(), TOL_0);
771-
assert_approx_eq!(ln_2, 2f16.ln(), TOL_0);
772-
assert_approx_eq!(ln_10, 10f16.ln(), TOL_0);
773-
}
774-
}
775-
776520
#[test]
777521
fn test_float_bits_conv() {
778522
assert_eq!((1f16).to_bits(), 0x3c00);

‎library/coretests/tests/floats/f32.rs

Lines changed: 75 additions & 315 deletions
Large diffs are not rendered by default.

‎library/coretests/tests/floats/f64.rs

Lines changed: 63 additions & 300 deletions
Large diffs are not rendered by default.

‎library/coretests/tests/floats/mod.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
#![feature(f16, f128, float_gamma, float_minimum_maximum)]
2-
31
use std::fmt;
42
use std::ops::{Add, Div, Mul, Rem, Sub};
53

‎library/coretests/tests/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#![feature(const_eval_select)]
1919
#![feature(const_swap_nonoverlapping)]
2020
#![feature(const_trait_impl)]
21+
#![feature(core_float_math)]
2122
#![feature(core_intrinsics)]
2223
#![feature(core_intrinsics_fallbacks)]
2324
#![feature(core_io_borrowed_buf)]
@@ -30,6 +31,8 @@
3031
#![feature(exact_size_is_empty)]
3132
#![feature(extend_one)]
3233
#![feature(extern_types)]
34+
#![feature(f128)]
35+
#![feature(f16)]
3336
#![feature(float_minimum_maximum)]
3437
#![feature(flt2dec)]
3538
#![feature(fmt_internals)]

‎library/std/tests/floats/f128.rs

Lines changed: 303 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,303 @@
1+
// FIXME(f16_f128): only tested on platforms that have symbols and aren't buggy
2+
#![cfg(reliable_f128)]
3+
4+
use std::f128::consts;
5+
#[cfg(reliable_f128_math)]
6+
use std::ops::Rem;
7+
use std::ops::{Add, Div, Mul, Sub};
8+
9+
// Note these tolerances make sense around zero, but not for more extreme exponents.
10+
11+
/// For operations that are near exact, usually not involving math of different
12+
/// signs.
13+
const TOL_PRECISE: f128 = 1e-28;
14+
15+
/// Tolerances for math that is allowed to be imprecise, usually due to multiple chained
16+
/// operations.
17+
#[cfg(reliable_f128_math)]
18+
const TOL_IMPR: f128 = 1e-10;
19+
20+
/// Compare by representation
21+
#[allow(unused_macros)]
22+
macro_rules! assert_f128_biteq {
23+
($a:expr, $b:expr) => {
24+
let (l, r): (&f128, &f128) = (&$a, &$b);
25+
let lb = l.to_bits();
26+
let rb = r.to_bits();
27+
assert_eq!(lb, rb, "float {l:?} is not bitequal to {r:?}.\na: {lb:#034x}\nb: {rb:#034x}");
28+
};
29+
}
30+
31+
#[test]
32+
fn test_num_f128() {
33+
// FIXME(f16_f128): replace with a `test_num` call once the required `fmodl`/`fmodf128`
34+
// function is available on all platforms.
35+
let ten = 10f128;
36+
let two = 2f128;
37+
assert_eq!(ten.add(two), ten + two);
38+
assert_eq!(ten.sub(two), ten - two);
39+
assert_eq!(ten.mul(two), ten * two);
40+
assert_eq!(ten.div(two), ten / two);
41+
}
42+
43+
// Many math functions allow for less accurate results, so the next tolerance up is used
44+
45+
#[test]
46+
#[cfg(reliable_f128_math)]
47+
fn test_powf() {
48+
let nan: f128 = f128::NAN;
49+
let inf: f128 = f128::INFINITY;
50+
let neg_inf: f128 = f128::NEG_INFINITY;
51+
assert_eq!(1.0f128.powf(1.0), 1.0);
52+
assert_approx_eq!(3.4f128.powf(4.5), 246.40818323761892815995637964326426756, TOL_IMPR);
53+
assert_approx_eq!(2.7f128.powf(-3.2), 0.041652009108526178281070304373500889273, TOL_IMPR);
54+
assert_approx_eq!((-3.1f128).powf(2.0), 9.6100000000000005506706202140776519387, TOL_IMPR);
55+
assert_approx_eq!(5.9f128.powf(-2.0), 0.028727377190462507313100483690639638451, TOL_IMPR);
56+
assert_eq!(8.3f128.powf(0.0), 1.0);
57+
assert!(nan.powf(2.0).is_nan());
58+
assert_eq!(inf.powf(2.0), inf);
59+
assert_eq!(neg_inf.powf(3.0), neg_inf);
60+
}
61+
62+
#[test]
63+
#[cfg(reliable_f128_math)]
64+
fn test_exp() {
65+
assert_eq!(1.0, 0.0f128.exp());
66+
assert_approx_eq!(consts::E, 1.0f128.exp(), TOL);
67+
assert_approx_eq!(148.41315910257660342111558004055227962348775, 5.0f128.exp(), TOL);
68+
69+
let inf: f128 = f128::INFINITY;
70+
let neg_inf: f128 = f128::NEG_INFINITY;
71+
let nan: f128 = f128::NAN;
72+
assert_eq!(inf, inf.exp());
73+
assert_eq!(0.0, neg_inf.exp());
74+
assert!(nan.exp().is_nan());
75+
}
76+
77+
#[test]
78+
#[cfg(reliable_f128_math)]
79+
fn test_exp2() {
80+
assert_eq!(32.0, 5.0f128.exp2());
81+
assert_eq!(1.0, 0.0f128.exp2());
82+
83+
let inf: f128 = f128::INFINITY;
84+
let neg_inf: f128 = f128::NEG_INFINITY;
85+
let nan: f128 = f128::NAN;
86+
assert_eq!(inf, inf.exp2());
87+
assert_eq!(0.0, neg_inf.exp2());
88+
assert!(nan.exp2().is_nan());
89+
}
90+
91+
#[test]
92+
#[cfg(reliable_f128_math)]
93+
fn test_ln() {
94+
let nan: f128 = f128::NAN;
95+
let inf: f128 = f128::INFINITY;
96+
let neg_inf: f128 = f128::NEG_INFINITY;
97+
assert_approx_eq!(1.0f128.exp().ln(), 1.0, TOL);
98+
assert!(nan.ln().is_nan());
99+
assert_eq!(inf.ln(), inf);
100+
assert!(neg_inf.ln().is_nan());
101+
assert!((-2.3f128).ln().is_nan());
102+
assert_eq!((-0.0f128).ln(), neg_inf);
103+
assert_eq!(0.0f128.ln(), neg_inf);
104+
assert_approx_eq!(4.0f128.ln(), 1.3862943611198906188344642429163531366, TOL);
105+
}
106+
107+
#[test]
108+
#[cfg(reliable_f128_math)]
109+
fn test_log() {
110+
let nan: f128 = f128::NAN;
111+
let inf: f128 = f128::INFINITY;
112+
let neg_inf: f128 = f128::NEG_INFINITY;
113+
assert_eq!(10.0f128.log(10.0), 1.0);
114+
assert_approx_eq!(2.3f128.log(3.5), 0.66485771361478710036766645911922010272, TOL);
115+
assert_eq!(1.0f128.exp().log(1.0f128.exp()), 1.0);
116+
assert!(1.0f128.log(1.0).is_nan());
117+
assert!(1.0f128.log(-13.9).is_nan());
118+
assert!(nan.log(2.3).is_nan());
119+
assert_eq!(inf.log(10.0), inf);
120+
assert!(neg_inf.log(8.8).is_nan());
121+
assert!((-2.3f128).log(0.1).is_nan());
122+
assert_eq!((-0.0f128).log(2.0), neg_inf);
123+
assert_eq!(0.0f128.log(7.0), neg_inf);
124+
}
125+
126+
#[test]
127+
#[cfg(reliable_f128_math)]
128+
fn test_log2() {
129+
let nan: f128 = f128::NAN;
130+
let inf: f128 = f128::INFINITY;
131+
let neg_inf: f128 = f128::NEG_INFINITY;
132+
assert_approx_eq!(10.0f128.log2(), 3.32192809488736234787031942948939017, TOL);
133+
assert_approx_eq!(2.3f128.log2(), 1.2016338611696504130002982471978765921, TOL);
134+
assert_approx_eq!(1.0f128.exp().log2(), 1.4426950408889634073599246810018921381, TOL);
135+
assert!(nan.log2().is_nan());
136+
assert_eq!(inf.log2(), inf);
137+
assert!(neg_inf.log2().is_nan());
138+
assert!((-2.3f128).log2().is_nan());
139+
assert_eq!((-0.0f128).log2(), neg_inf);
140+
assert_eq!(0.0f128.log2(), neg_inf);
141+
}
142+
143+
#[test]
144+
#[cfg(reliable_f128_math)]
145+
fn test_log10() {
146+
let nan: f128 = f128::NAN;
147+
let inf: f128 = f128::INFINITY;
148+
let neg_inf: f128 = f128::NEG_INFINITY;
149+
assert_eq!(10.0f128.log10(), 1.0);
150+
assert_approx_eq!(2.3f128.log10(), 0.36172783601759284532595218865859309898, TOL);
151+
assert_approx_eq!(1.0f128.exp().log10(), 0.43429448190325182765112891891660508222, TOL);
152+
assert_eq!(1.0f128.log10(), 0.0);
153+
assert!(nan.log10().is_nan());
154+
assert_eq!(inf.log10(), inf);
155+
assert!(neg_inf.log10().is_nan());
156+
assert!((-2.3f128).log10().is_nan());
157+
assert_eq!((-0.0f128).log10(), neg_inf);
158+
assert_eq!(0.0f128.log10(), neg_inf);
159+
}
160+
161+
#[test]
162+
#[cfg(reliable_f128_math)]
163+
fn test_asinh() {
164+
// Lower accuracy results are allowed, use increased tolerances
165+
assert_eq!(0.0f128.asinh(), 0.0f128);
166+
assert_eq!((-0.0f128).asinh(), -0.0f128);
167+
168+
let inf: f128 = f128::INFINITY;
169+
let neg_inf: f128 = f128::NEG_INFINITY;
170+
let nan: f128 = f128::NAN;
171+
assert_eq!(inf.asinh(), inf);
172+
assert_eq!(neg_inf.asinh(), neg_inf);
173+
assert!(nan.asinh().is_nan());
174+
assert!((-0.0f128).asinh().is_sign_negative());
175+
176+
// issue 63271
177+
assert_approx_eq!(2.0f128.asinh(), 1.443635475178810342493276740273105f128, TOL_IMPR);
178+
assert_approx_eq!((-2.0f128).asinh(), -1.443635475178810342493276740273105f128, TOL_IMPR);
179+
// regression test for the catastrophic cancellation fixed in 72486
180+
assert_approx_eq!(
181+
(-67452098.07139316f128).asinh(),
182+
-18.720075426274544393985484294000831757220,
183+
TOL_IMPR
184+
);
185+
186+
// test for low accuracy from issue 104548
187+
assert_approx_eq!(60.0f128, 60.0f128.sinh().asinh(), TOL_IMPR);
188+
// mul needed for approximate comparison to be meaningful
189+
assert_approx_eq!(1.0f128, 1e-15f128.sinh().asinh() * 1e15f128, TOL_IMPR);
190+
}
191+
192+
#[test]
193+
#[cfg(reliable_f128_math)]
194+
fn test_acosh() {
195+
assert_eq!(1.0f128.acosh(), 0.0f128);
196+
assert!(0.999f128.acosh().is_nan());
197+
198+
let inf: f128 = f128::INFINITY;
199+
let neg_inf: f128 = f128::NEG_INFINITY;
200+
let nan: f128 = f128::NAN;
201+
assert_eq!(inf.acosh(), inf);
202+
assert!(neg_inf.acosh().is_nan());
203+
assert!(nan.acosh().is_nan());
204+
assert_approx_eq!(2.0f128.acosh(), 1.31695789692481670862504634730796844f128, TOL_IMPR);
205+
assert_approx_eq!(3.0f128.acosh(), 1.76274717403908605046521864995958461f128, TOL_IMPR);
206+
207+
// test for low accuracy from issue 104548
208+
assert_approx_eq!(60.0f128, 60.0f128.cosh().acosh(), TOL_IMPR);
209+
}
210+
211+
#[test]
212+
#[cfg(reliable_f128_math)]
213+
fn test_atanh() {
214+
assert_eq!(0.0f128.atanh(), 0.0f128);
215+
assert_eq!((-0.0f128).atanh(), -0.0f128);
216+
217+
let inf: f128 = f128::INFINITY;
218+
let neg_inf: f128 = f128::NEG_INFINITY;
219+
let nan: f128 = f128::NAN;
220+
assert_eq!(1.0f128.atanh(), inf);
221+
assert_eq!((-1.0f128).atanh(), neg_inf);
222+
assert!(2f128.atanh().atanh().is_nan());
223+
assert!((-2f128).atanh().atanh().is_nan());
224+
assert!(inf.atanh().is_nan());
225+
assert!(neg_inf.atanh().is_nan());
226+
assert!(nan.atanh().is_nan());
227+
assert_approx_eq!(0.5f128.atanh(), 0.54930614433405484569762261846126285f128, TOL_IMPR);
228+
assert_approx_eq!((-0.5f128).atanh(), -0.54930614433405484569762261846126285f128, TOL_IMPR);
229+
}
230+
231+
#[test]
232+
#[cfg(reliable_f128_math)]
233+
fn test_gamma() {
234+
// precision can differ among platforms
235+
assert_approx_eq!(1.0f128.gamma(), 1.0f128, TOL_IMPR);
236+
assert_approx_eq!(2.0f128.gamma(), 1.0f128, TOL_IMPR);
237+
assert_approx_eq!(3.0f128.gamma(), 2.0f128, TOL_IMPR);
238+
assert_approx_eq!(4.0f128.gamma(), 6.0f128, TOL_IMPR);
239+
assert_approx_eq!(5.0f128.gamma(), 24.0f128, TOL_IMPR);
240+
assert_approx_eq!(0.5f128.gamma(), consts::PI.sqrt(), TOL_IMPR);
241+
assert_approx_eq!((-0.5f128).gamma(), -2.0 * consts::PI.sqrt(), TOL_IMPR);
242+
assert_eq!(0.0f128.gamma(), f128::INFINITY);
243+
assert_eq!((-0.0f128).gamma(), f128::NEG_INFINITY);
244+
assert!((-1.0f128).gamma().is_nan());
245+
assert!((-2.0f128).gamma().is_nan());
246+
assert!(f128::NAN.gamma().is_nan());
247+
assert!(f128::NEG_INFINITY.gamma().is_nan());
248+
assert_eq!(f128::INFINITY.gamma(), f128::INFINITY);
249+
assert_eq!(1760.9f128.gamma(), f128::INFINITY);
250+
}
251+
252+
#[test]
253+
#[cfg(reliable_f128_math)]
254+
fn test_ln_gamma() {
255+
assert_approx_eq!(1.0f128.ln_gamma().0, 0.0f128, TOL_IMPR);
256+
assert_eq!(1.0f128.ln_gamma().1, 1);
257+
assert_approx_eq!(2.0f128.ln_gamma().0, 0.0f128, TOL_IMPR);
258+
assert_eq!(2.0f128.ln_gamma().1, 1);
259+
assert_approx_eq!(3.0f128.ln_gamma().0, 2.0f128.ln(), TOL_IMPR);
260+
assert_eq!(3.0f128.ln_gamma().1, 1);
261+
assert_approx_eq!((-0.5f128).ln_gamma().0, (2.0 * consts::PI.sqrt()).ln(), TOL_IMPR);
262+
assert_eq!((-0.5f128).ln_gamma().1, -1);
263+
}
264+
265+
#[test]
266+
fn test_real_consts() {
267+
let pi: f128 = consts::PI;
268+
let frac_pi_2: f128 = consts::FRAC_PI_2;
269+
let frac_pi_3: f128 = consts::FRAC_PI_3;
270+
let frac_pi_4: f128 = consts::FRAC_PI_4;
271+
let frac_pi_6: f128 = consts::FRAC_PI_6;
272+
let frac_pi_8: f128 = consts::FRAC_PI_8;
273+
let frac_1_pi: f128 = consts::FRAC_1_PI;
274+
let frac_2_pi: f128 = consts::FRAC_2_PI;
275+
276+
assert_approx_eq!(frac_pi_2, pi / 2f128, TOL_PRECISE);
277+
assert_approx_eq!(frac_pi_3, pi / 3f128, TOL_PRECISE);
278+
assert_approx_eq!(frac_pi_4, pi / 4f128, TOL_PRECISE);
279+
assert_approx_eq!(frac_pi_6, pi / 6f128, TOL_PRECISE);
280+
assert_approx_eq!(frac_pi_8, pi / 8f128, TOL_PRECISE);
281+
assert_approx_eq!(frac_1_pi, 1f128 / pi, TOL_PRECISE);
282+
assert_approx_eq!(frac_2_pi, 2f128 / pi, TOL_PRECISE);
283+
284+
#[cfg(reliable_f128_math)]
285+
{
286+
let frac_2_sqrtpi: f128 = consts::FRAC_2_SQRT_PI;
287+
let sqrt2: f128 = consts::SQRT_2;
288+
let frac_1_sqrt2: f128 = consts::FRAC_1_SQRT_2;
289+
let e: f128 = consts::E;
290+
let log2_e: f128 = consts::LOG2_E;
291+
let log10_e: f128 = consts::LOG10_E;
292+
let ln_2: f128 = consts::LN_2;
293+
let ln_10: f128 = consts::LN_10;
294+
295+
assert_approx_eq!(frac_2_sqrtpi, 2f128 / pi.sqrt(), TOL_PRECISE);
296+
assert_approx_eq!(sqrt2, 2f128.sqrt(), TOL_PRECISE);
297+
assert_approx_eq!(frac_1_sqrt2, 1f128 / 2f128.sqrt(), TOL_PRECISE);
298+
assert_approx_eq!(log2_e, e.log2(), TOL_PRECISE);
299+
assert_approx_eq!(log10_e, e.log10(), TOL_PRECISE);
300+
assert_approx_eq!(ln_2, 2f128.ln(), TOL_PRECISE);
301+
assert_approx_eq!(ln_10, 10f128.ln(), TOL_PRECISE);
302+
}
303+
}

‎library/std/tests/floats/f16.rs

Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
// FIXME(f16_f128): only tested on platforms that have symbols and aren't buggy
2+
#![cfg(reliable_f16)]
3+
4+
use std::f16::consts;
5+
6+
/// Tolerance for results on the order of 10.0e-2
7+
#[allow(unused)]
8+
const TOL_N2: f16 = 0.0001;
9+
10+
/// Tolerance for results on the order of 10.0e+0
11+
#[allow(unused)]
12+
const TOL_0: f16 = 0.01;
13+
14+
/// Tolerance for results on the order of 10.0e+2
15+
#[allow(unused)]
16+
const TOL_P2: f16 = 0.5;
17+
18+
/// Tolerance for results on the order of 10.0e+4
19+
#[allow(unused)]
20+
const TOL_P4: f16 = 10.0;
21+
22+
/// Compare by representation
23+
#[allow(unused_macros)]
24+
macro_rules! assert_f16_biteq {
25+
($a:expr, $b:expr) => {
26+
let (l, r): (&f16, &f16) = (&$a, &$b);
27+
let lb = l.to_bits();
28+
let rb = r.to_bits();
29+
assert_eq!(lb, rb, "float {l:?} ({lb:#04x}) is not bitequal to {r:?} ({rb:#04x})");
30+
};
31+
}
32+
33+
#[test]
34+
#[cfg(reliable_f16_math)]
35+
fn test_powf() {
36+
let nan: f16 = f16::NAN;
37+
let inf: f16 = f16::INFINITY;
38+
let neg_inf: f16 = f16::NEG_INFINITY;
39+
assert_eq!(1.0f16.powf(1.0), 1.0);
40+
assert_approx_eq!(3.4f16.powf(4.5), 246.408183, TOL_P2);
41+
assert_approx_eq!(2.7f16.powf(-3.2), 0.041652, TOL_N2);
42+
assert_approx_eq!((-3.1f16).powf(2.0), 9.61, TOL_P2);
43+
assert_approx_eq!(5.9f16.powf(-2.0), 0.028727, TOL_N2);
44+
assert_eq!(8.3f16.powf(0.0), 1.0);
45+
assert!(nan.powf(2.0).is_nan());
46+
assert_eq!(inf.powf(2.0), inf);
47+
assert_eq!(neg_inf.powf(3.0), neg_inf);
48+
}
49+
50+
#[test]
51+
#[cfg(reliable_f16_math)]
52+
fn test_exp() {
53+
assert_eq!(1.0, 0.0f16.exp());
54+
assert_approx_eq!(2.718282, 1.0f16.exp(), TOL_0);
55+
assert_approx_eq!(148.413159, 5.0f16.exp(), TOL_0);
56+
57+
let inf: f16 = f16::INFINITY;
58+
let neg_inf: f16 = f16::NEG_INFINITY;
59+
let nan: f16 = f16::NAN;
60+
assert_eq!(inf, inf.exp());
61+
assert_eq!(0.0, neg_inf.exp());
62+
assert!(nan.exp().is_nan());
63+
}
64+
65+
#[test]
66+
#[cfg(reliable_f16_math)]
67+
fn test_exp2() {
68+
assert_eq!(32.0, 5.0f16.exp2());
69+
assert_eq!(1.0, 0.0f16.exp2());
70+
71+
let inf: f16 = f16::INFINITY;
72+
let neg_inf: f16 = f16::NEG_INFINITY;
73+
let nan: f16 = f16::NAN;
74+
assert_eq!(inf, inf.exp2());
75+
assert_eq!(0.0, neg_inf.exp2());
76+
assert!(nan.exp2().is_nan());
77+
}
78+
79+
#[test]
80+
#[cfg(reliable_f16_math)]
81+
fn test_ln() {
82+
let nan: f16 = f16::NAN;
83+
let inf: f16 = f16::INFINITY;
84+
let neg_inf: f16 = f16::NEG_INFINITY;
85+
assert_approx_eq!(1.0f16.exp().ln(), 1.0, TOL_0);
86+
assert!(nan.ln().is_nan());
87+
assert_eq!(inf.ln(), inf);
88+
assert!(neg_inf.ln().is_nan());
89+
assert!((-2.3f16).ln().is_nan());
90+
assert_eq!((-0.0f16).ln(), neg_inf);
91+
assert_eq!(0.0f16.ln(), neg_inf);
92+
assert_approx_eq!(4.0f16.ln(), 1.386294, TOL_0);
93+
}
94+
95+
#[test]
96+
#[cfg(reliable_f16_math)]
97+
fn test_log() {
98+
let nan: f16 = f16::NAN;
99+
let inf: f16 = f16::INFINITY;
100+
let neg_inf: f16 = f16::NEG_INFINITY;
101+
assert_eq!(10.0f16.log(10.0), 1.0);
102+
assert_approx_eq!(2.3f16.log(3.5), 0.664858, TOL_0);
103+
assert_eq!(1.0f16.exp().log(1.0f16.exp()), 1.0);
104+
assert!(1.0f16.log(1.0).is_nan());
105+
assert!(1.0f16.log(-13.9).is_nan());
106+
assert!(nan.log(2.3).is_nan());
107+
assert_eq!(inf.log(10.0), inf);
108+
assert!(neg_inf.log(8.8).is_nan());
109+
assert!((-2.3f16).log(0.1).is_nan());
110+
assert_eq!((-0.0f16).log(2.0), neg_inf);
111+
assert_eq!(0.0f16.log(7.0), neg_inf);
112+
}
113+
114+
#[test]
115+
#[cfg(reliable_f16_math)]
116+
fn test_log2() {
117+
let nan: f16 = f16::NAN;
118+
let inf: f16 = f16::INFINITY;
119+
let neg_inf: f16 = f16::NEG_INFINITY;
120+
assert_approx_eq!(10.0f16.log2(), 3.321928, TOL_0);
121+
assert_approx_eq!(2.3f16.log2(), 1.201634, TOL_0);
122+
assert_approx_eq!(1.0f16.exp().log2(), 1.442695, TOL_0);
123+
assert!(nan.log2().is_nan());
124+
assert_eq!(inf.log2(), inf);
125+
assert!(neg_inf.log2().is_nan());
126+
assert!((-2.3f16).log2().is_nan());
127+
assert_eq!((-0.0f16).log2(), neg_inf);
128+
assert_eq!(0.0f16.log2(), neg_inf);
129+
}
130+
131+
#[test]
132+
#[cfg(reliable_f16_math)]
133+
fn test_log10() {
134+
let nan: f16 = f16::NAN;
135+
let inf: f16 = f16::INFINITY;
136+
let neg_inf: f16 = f16::NEG_INFINITY;
137+
assert_eq!(10.0f16.log10(), 1.0);
138+
assert_approx_eq!(2.3f16.log10(), 0.361728, TOL_0);
139+
assert_approx_eq!(1.0f16.exp().log10(), 0.434294, TOL_0);
140+
assert_eq!(1.0f16.log10(), 0.0);
141+
assert!(nan.log10().is_nan());
142+
assert_eq!(inf.log10(), inf);
143+
assert!(neg_inf.log10().is_nan());
144+
assert!((-2.3f16).log10().is_nan());
145+
assert_eq!((-0.0f16).log10(), neg_inf);
146+
assert_eq!(0.0f16.log10(), neg_inf);
147+
}
148+
149+
#[test]
150+
fn test_real_consts() {
151+
// FIXME(f16_f128): add math tests when available
152+
153+
let pi: f16 = consts::PI;
154+
let frac_pi_2: f16 = consts::FRAC_PI_2;
155+
let frac_pi_3: f16 = consts::FRAC_PI_3;
156+
let frac_pi_4: f16 = consts::FRAC_PI_4;
157+
let frac_pi_6: f16 = consts::FRAC_PI_6;
158+
let frac_pi_8: f16 = consts::FRAC_PI_8;
159+
let frac_1_pi: f16 = consts::FRAC_1_PI;
160+
let frac_2_pi: f16 = consts::FRAC_2_PI;
161+
162+
assert_approx_eq!(frac_pi_2, pi / 2f16, TOL_0);
163+
assert_approx_eq!(frac_pi_3, pi / 3f16, TOL_0);
164+
assert_approx_eq!(frac_pi_4, pi / 4f16, TOL_0);
165+
assert_approx_eq!(frac_pi_6, pi / 6f16, TOL_0);
166+
assert_approx_eq!(frac_pi_8, pi / 8f16, TOL_0);
167+
assert_approx_eq!(frac_1_pi, 1f16 / pi, TOL_0);
168+
assert_approx_eq!(frac_2_pi, 2f16 / pi, TOL_0);
169+
170+
#[cfg(reliable_f16_math)]
171+
{
172+
let frac_2_sqrtpi: f16 = consts::FRAC_2_SQRT_PI;
173+
let sqrt2: f16 = consts::SQRT_2;
174+
let frac_1_sqrt2: f16 = consts::FRAC_1_SQRT_2;
175+
let e: f16 = consts::E;
176+
let log2_e: f16 = consts::LOG2_E;
177+
let log10_e: f16 = consts::LOG10_E;
178+
let ln_2: f16 = consts::LN_2;
179+
let ln_10: f16 = consts::LN_10;
180+
181+
assert_approx_eq!(frac_2_sqrtpi, 2f16 / pi.sqrt(), TOL_0);
182+
assert_approx_eq!(sqrt2, 2f16.sqrt(), TOL_0);
183+
assert_approx_eq!(frac_1_sqrt2, 1f16 / 2f16.sqrt(), TOL_0);
184+
assert_approx_eq!(log2_e, e.log2(), TOL_0);
185+
assert_approx_eq!(log10_e, e.log10(), TOL_0);
186+
assert_approx_eq!(ln_2, 2f16.ln(), TOL_0);
187+
assert_approx_eq!(ln_10, 10f16.ln(), TOL_0);
188+
}
189+
}

‎library/std/tests/floats/f32.rs

Lines changed: 253 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,253 @@
1+
use std::f32::consts;
2+
3+
#[allow(unused_macros)]
4+
macro_rules! assert_f32_biteq {
5+
($left : expr, $right : expr) => {
6+
let l: &f32 = &$left;
7+
let r: &f32 = &$right;
8+
let lb = l.to_bits();
9+
let rb = r.to_bits();
10+
assert_eq!(lb, rb, "float {l} ({lb:#010x}) is not bitequal to {r} ({rb:#010x})");
11+
};
12+
}
13+
14+
#[test]
15+
fn test_powf() {
16+
let nan: f32 = f32::NAN;
17+
let inf: f32 = f32::INFINITY;
18+
let neg_inf: f32 = f32::NEG_INFINITY;
19+
assert_eq!(1.0f32.powf(1.0), 1.0);
20+
assert_approx_eq!(3.4f32.powf(4.5), 246.408218);
21+
assert_approx_eq!(2.7f32.powf(-3.2), 0.041652);
22+
assert_approx_eq!((-3.1f32).powf(2.0), 9.61);
23+
assert_approx_eq!(5.9f32.powf(-2.0), 0.028727);
24+
assert_eq!(8.3f32.powf(0.0), 1.0);
25+
assert!(nan.powf(2.0).is_nan());
26+
assert_eq!(inf.powf(2.0), inf);
27+
assert_eq!(neg_inf.powf(3.0), neg_inf);
28+
}
29+
30+
#[test]
31+
fn test_exp() {
32+
assert_eq!(1.0, 0.0f32.exp());
33+
assert_approx_eq!(2.718282, 1.0f32.exp());
34+
assert_approx_eq!(148.413162, 5.0f32.exp());
35+
36+
let inf: f32 = f32::INFINITY;
37+
let neg_inf: f32 = f32::NEG_INFINITY;
38+
let nan: f32 = f32::NAN;
39+
assert_eq!(inf, inf.exp());
40+
assert_eq!(0.0, neg_inf.exp());
41+
assert!(nan.exp().is_nan());
42+
}
43+
44+
#[test]
45+
fn test_exp2() {
46+
assert_eq!(32.0, 5.0f32.exp2());
47+
assert_eq!(1.0, 0.0f32.exp2());
48+
49+
let inf: f32 = f32::INFINITY;
50+
let neg_inf: f32 = f32::NEG_INFINITY;
51+
let nan: f32 = f32::NAN;
52+
assert_eq!(inf, inf.exp2());
53+
assert_eq!(0.0, neg_inf.exp2());
54+
assert!(nan.exp2().is_nan());
55+
}
56+
57+
#[test]
58+
fn test_ln() {
59+
let nan: f32 = f32::NAN;
60+
let inf: f32 = f32::INFINITY;
61+
let neg_inf: f32 = f32::NEG_INFINITY;
62+
assert_approx_eq!(1.0f32.exp().ln(), 1.0);
63+
assert!(nan.ln().is_nan());
64+
assert_eq!(inf.ln(), inf);
65+
assert!(neg_inf.ln().is_nan());
66+
assert!((-2.3f32).ln().is_nan());
67+
assert_eq!((-0.0f32).ln(), neg_inf);
68+
assert_eq!(0.0f32.ln(), neg_inf);
69+
assert_approx_eq!(4.0f32.ln(), 1.386294);
70+
}
71+
72+
#[test]
73+
fn test_log() {
74+
let nan: f32 = f32::NAN;
75+
let inf: f32 = f32::INFINITY;
76+
let neg_inf: f32 = f32::NEG_INFINITY;
77+
assert_eq!(10.0f32.log(10.0), 1.0);
78+
assert_approx_eq!(2.3f32.log(3.5), 0.664858);
79+
assert_eq!(1.0f32.exp().log(1.0f32.exp()), 1.0);
80+
assert!(1.0f32.log(1.0).is_nan());
81+
assert!(1.0f32.log(-13.9).is_nan());
82+
assert!(nan.log(2.3).is_nan());
83+
assert_eq!(inf.log(10.0), inf);
84+
assert!(neg_inf.log(8.8).is_nan());
85+
assert!((-2.3f32).log(0.1).is_nan());
86+
assert_eq!((-0.0f32).log(2.0), neg_inf);
87+
assert_eq!(0.0f32.log(7.0), neg_inf);
88+
}
89+
90+
#[test]
91+
fn test_log2() {
92+
let nan: f32 = f32::NAN;
93+
let inf: f32 = f32::INFINITY;
94+
let neg_inf: f32 = f32::NEG_INFINITY;
95+
assert_approx_eq!(10.0f32.log2(), 3.321928);
96+
assert_approx_eq!(2.3f32.log2(), 1.201634);
97+
assert_approx_eq!(1.0f32.exp().log2(), 1.442695);
98+
assert!(nan.log2().is_nan());
99+
assert_eq!(inf.log2(), inf);
100+
assert!(neg_inf.log2().is_nan());
101+
assert!((-2.3f32).log2().is_nan());
102+
assert_eq!((-0.0f32).log2(), neg_inf);
103+
assert_eq!(0.0f32.log2(), neg_inf);
104+
}
105+
106+
#[test]
107+
fn test_log10() {
108+
let nan: f32 = f32::NAN;
109+
let inf: f32 = f32::INFINITY;
110+
let neg_inf: f32 = f32::NEG_INFINITY;
111+
assert_eq!(10.0f32.log10(), 1.0);
112+
assert_approx_eq!(2.3f32.log10(), 0.361728);
113+
assert_approx_eq!(1.0f32.exp().log10(), 0.434294);
114+
assert_eq!(1.0f32.log10(), 0.0);
115+
assert!(nan.log10().is_nan());
116+
assert_eq!(inf.log10(), inf);
117+
assert!(neg_inf.log10().is_nan());
118+
assert!((-2.3f32).log10().is_nan());
119+
assert_eq!((-0.0f32).log10(), neg_inf);
120+
assert_eq!(0.0f32.log10(), neg_inf);
121+
}
122+
123+
#[test]
124+
fn test_asinh() {
125+
assert_eq!(0.0f32.asinh(), 0.0f32);
126+
assert_eq!((-0.0f32).asinh(), -0.0f32);
127+
128+
let inf: f32 = f32::INFINITY;
129+
let neg_inf: f32 = f32::NEG_INFINITY;
130+
let nan: f32 = f32::NAN;
131+
assert_eq!(inf.asinh(), inf);
132+
assert_eq!(neg_inf.asinh(), neg_inf);
133+
assert!(nan.asinh().is_nan());
134+
assert!((-0.0f32).asinh().is_sign_negative()); // issue 63271
135+
assert_approx_eq!(2.0f32.asinh(), 1.443635475178810342493276740273105f32);
136+
assert_approx_eq!((-2.0f32).asinh(), -1.443635475178810342493276740273105f32);
137+
// regression test for the catastrophic cancellation fixed in 72486
138+
assert_approx_eq!((-3000.0f32).asinh(), -8.699514775987968673236893537700647f32);
139+
140+
// test for low accuracy from issue 104548
141+
assert_approx_eq!(60.0f32, 60.0f32.sinh().asinh());
142+
// mul needed for approximate comparison to be meaningful
143+
assert_approx_eq!(1.0f32, 1e-15f32.sinh().asinh() * 1e15f32);
144+
}
145+
146+
#[test]
147+
fn test_acosh() {
148+
assert_eq!(1.0f32.acosh(), 0.0f32);
149+
assert!(0.999f32.acosh().is_nan());
150+
151+
let inf: f32 = f32::INFINITY;
152+
let neg_inf: f32 = f32::NEG_INFINITY;
153+
let nan: f32 = f32::NAN;
154+
assert_eq!(inf.acosh(), inf);
155+
assert!(neg_inf.acosh().is_nan());
156+
assert!(nan.acosh().is_nan());
157+
assert_approx_eq!(2.0f32.acosh(), 1.31695789692481670862504634730796844f32);
158+
assert_approx_eq!(3.0f32.acosh(), 1.76274717403908605046521864995958461f32);
159+
160+
// test for low accuracy from issue 104548
161+
assert_approx_eq!(60.0f32, 60.0f32.cosh().acosh());
162+
}
163+
164+
#[test]
165+
fn test_atanh() {
166+
assert_eq!(0.0f32.atanh(), 0.0f32);
167+
assert_eq!((-0.0f32).atanh(), -0.0f32);
168+
169+
let inf32: f32 = f32::INFINITY;
170+
let neg_inf32: f32 = f32::NEG_INFINITY;
171+
assert_eq!(1.0f32.atanh(), inf32);
172+
assert_eq!((-1.0f32).atanh(), neg_inf32);
173+
174+
assert!(2f64.atanh().atanh().is_nan());
175+
assert!((-2f64).atanh().atanh().is_nan());
176+
177+
let inf64: f32 = f32::INFINITY;
178+
let neg_inf64: f32 = f32::NEG_INFINITY;
179+
let nan32: f32 = f32::NAN;
180+
assert!(inf64.atanh().is_nan());
181+
assert!(neg_inf64.atanh().is_nan());
182+
assert!(nan32.atanh().is_nan());
183+
184+
assert_approx_eq!(0.5f32.atanh(), 0.54930614433405484569762261846126285f32);
185+
assert_approx_eq!((-0.5f32).atanh(), -0.54930614433405484569762261846126285f32);
186+
}
187+
188+
#[test]
189+
fn test_gamma() {
190+
// precision can differ between platforms
191+
assert_approx_eq!(1.0f32.gamma(), 1.0f32);
192+
assert_approx_eq!(2.0f32.gamma(), 1.0f32);
193+
assert_approx_eq!(3.0f32.gamma(), 2.0f32);
194+
assert_approx_eq!(4.0f32.gamma(), 6.0f32);
195+
assert_approx_eq!(5.0f32.gamma(), 24.0f32);
196+
assert_approx_eq!(0.5f32.gamma(), consts::PI.sqrt());
197+
assert_approx_eq!((-0.5f32).gamma(), -2.0 * consts::PI.sqrt());
198+
assert_eq!(0.0f32.gamma(), f32::INFINITY);
199+
assert_eq!((-0.0f32).gamma(), f32::NEG_INFINITY);
200+
assert!((-1.0f32).gamma().is_nan());
201+
assert!((-2.0f32).gamma().is_nan());
202+
assert!(f32::NAN.gamma().is_nan());
203+
assert!(f32::NEG_INFINITY.gamma().is_nan());
204+
assert_eq!(f32::INFINITY.gamma(), f32::INFINITY);
205+
assert_eq!(171.71f32.gamma(), f32::INFINITY);
206+
}
207+
208+
#[test]
209+
fn test_ln_gamma() {
210+
assert_approx_eq!(1.0f32.ln_gamma().0, 0.0f32);
211+
assert_eq!(1.0f32.ln_gamma().1, 1);
212+
assert_approx_eq!(2.0f32.ln_gamma().0, 0.0f32);
213+
assert_eq!(2.0f32.ln_gamma().1, 1);
214+
assert_approx_eq!(3.0f32.ln_gamma().0, 2.0f32.ln());
215+
assert_eq!(3.0f32.ln_gamma().1, 1);
216+
assert_approx_eq!((-0.5f32).ln_gamma().0, (2.0 * consts::PI.sqrt()).ln());
217+
assert_eq!((-0.5f32).ln_gamma().1, -1);
218+
}
219+
220+
#[test]
221+
fn test_real_consts() {
222+
let pi: f32 = consts::PI;
223+
let frac_pi_2: f32 = consts::FRAC_PI_2;
224+
let frac_pi_3: f32 = consts::FRAC_PI_3;
225+
let frac_pi_4: f32 = consts::FRAC_PI_4;
226+
let frac_pi_6: f32 = consts::FRAC_PI_6;
227+
let frac_pi_8: f32 = consts::FRAC_PI_8;
228+
let frac_1_pi: f32 = consts::FRAC_1_PI;
229+
let frac_2_pi: f32 = consts::FRAC_2_PI;
230+
let frac_2_sqrtpi: f32 = consts::FRAC_2_SQRT_PI;
231+
let sqrt2: f32 = consts::SQRT_2;
232+
let frac_1_sqrt2: f32 = consts::FRAC_1_SQRT_2;
233+
let e: f32 = consts::E;
234+
let log2_e: f32 = consts::LOG2_E;
235+
let log10_e: f32 = consts::LOG10_E;
236+
let ln_2: f32 = consts::LN_2;
237+
let ln_10: f32 = consts::LN_10;
238+
239+
assert_approx_eq!(frac_pi_2, pi / 2f32);
240+
assert_approx_eq!(frac_pi_3, pi / 3f32);
241+
assert_approx_eq!(frac_pi_4, pi / 4f32);
242+
assert_approx_eq!(frac_pi_6, pi / 6f32);
243+
assert_approx_eq!(frac_pi_8, pi / 8f32);
244+
assert_approx_eq!(frac_1_pi, 1f32 / pi);
245+
assert_approx_eq!(frac_2_pi, 2f32 / pi);
246+
assert_approx_eq!(frac_2_sqrtpi, 2f32 / pi.sqrt());
247+
assert_approx_eq!(sqrt2, 2f32.sqrt());
248+
assert_approx_eq!(frac_1_sqrt2, 1f32 / 2f32.sqrt());
249+
assert_approx_eq!(log2_e, e.log2());
250+
assert_approx_eq!(log10_e, e.log10());
251+
assert_approx_eq!(ln_2, 2f32.ln());
252+
assert_approx_eq!(ln_10, 10f32.ln());
253+
}

‎library/std/tests/floats/f64.rs

Lines changed: 249 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,249 @@
1+
use std::f64::consts;
2+
3+
#[allow(unused_macros)]
4+
macro_rules! assert_f64_biteq {
5+
($left : expr, $right : expr) => {
6+
let l: &f64 = &$left;
7+
let r: &f64 = &$right;
8+
let lb = l.to_bits();
9+
let rb = r.to_bits();
10+
assert_eq!(lb, rb, "float {l} ({lb:#018x}) is not bitequal to {r} ({rb:#018x})");
11+
};
12+
}
13+
14+
#[test]
15+
fn test_powf() {
16+
let nan: f64 = f64::NAN;
17+
let inf: f64 = f64::INFINITY;
18+
let neg_inf: f64 = f64::NEG_INFINITY;
19+
assert_eq!(1.0f64.powf(1.0), 1.0);
20+
assert_approx_eq!(3.4f64.powf(4.5), 246.408183);
21+
assert_approx_eq!(2.7f64.powf(-3.2), 0.041652);
22+
assert_approx_eq!((-3.1f64).powf(2.0), 9.61);
23+
assert_approx_eq!(5.9f64.powf(-2.0), 0.028727);
24+
assert_eq!(8.3f64.powf(0.0), 1.0);
25+
assert!(nan.powf(2.0).is_nan());
26+
assert_eq!(inf.powf(2.0), inf);
27+
assert_eq!(neg_inf.powf(3.0), neg_inf);
28+
}
29+
30+
#[test]
31+
fn test_exp() {
32+
assert_eq!(1.0, 0.0f64.exp());
33+
assert_approx_eq!(2.718282, 1.0f64.exp());
34+
assert_approx_eq!(148.413159, 5.0f64.exp());
35+
36+
let inf: f64 = f64::INFINITY;
37+
let neg_inf: f64 = f64::NEG_INFINITY;
38+
let nan: f64 = f64::NAN;
39+
assert_eq!(inf, inf.exp());
40+
assert_eq!(0.0, neg_inf.exp());
41+
assert!(nan.exp().is_nan());
42+
}
43+
44+
#[test]
45+
fn test_exp2() {
46+
assert_eq!(32.0, 5.0f64.exp2());
47+
assert_eq!(1.0, 0.0f64.exp2());
48+
49+
let inf: f64 = f64::INFINITY;
50+
let neg_inf: f64 = f64::NEG_INFINITY;
51+
let nan: f64 = f64::NAN;
52+
assert_eq!(inf, inf.exp2());
53+
assert_eq!(0.0, neg_inf.exp2());
54+
assert!(nan.exp2().is_nan());
55+
}
56+
57+
#[test]
58+
fn test_ln() {
59+
let nan: f64 = f64::NAN;
60+
let inf: f64 = f64::INFINITY;
61+
let neg_inf: f64 = f64::NEG_INFINITY;
62+
assert_approx_eq!(1.0f64.exp().ln(), 1.0);
63+
assert!(nan.ln().is_nan());
64+
assert_eq!(inf.ln(), inf);
65+
assert!(neg_inf.ln().is_nan());
66+
assert!((-2.3f64).ln().is_nan());
67+
assert_eq!((-0.0f64).ln(), neg_inf);
68+
assert_eq!(0.0f64.ln(), neg_inf);
69+
assert_approx_eq!(4.0f64.ln(), 1.386294);
70+
}
71+
72+
#[test]
73+
fn test_log() {
74+
let nan: f64 = f64::NAN;
75+
let inf: f64 = f64::INFINITY;
76+
let neg_inf: f64 = f64::NEG_INFINITY;
77+
assert_eq!(10.0f64.log(10.0), 1.0);
78+
assert_approx_eq!(2.3f64.log(3.5), 0.664858);
79+
assert_eq!(1.0f64.exp().log(1.0f64.exp()), 1.0);
80+
assert!(1.0f64.log(1.0).is_nan());
81+
assert!(1.0f64.log(-13.9).is_nan());
82+
assert!(nan.log(2.3).is_nan());
83+
assert_eq!(inf.log(10.0), inf);
84+
assert!(neg_inf.log(8.8).is_nan());
85+
assert!((-2.3f64).log(0.1).is_nan());
86+
assert_eq!((-0.0f64).log(2.0), neg_inf);
87+
assert_eq!(0.0f64.log(7.0), neg_inf);
88+
}
89+
90+
#[test]
91+
fn test_log2() {
92+
let nan: f64 = f64::NAN;
93+
let inf: f64 = f64::INFINITY;
94+
let neg_inf: f64 = f64::NEG_INFINITY;
95+
assert_approx_eq!(10.0f64.log2(), 3.321928);
96+
assert_approx_eq!(2.3f64.log2(), 1.201634);
97+
assert_approx_eq!(1.0f64.exp().log2(), 1.442695);
98+
assert!(nan.log2().is_nan());
99+
assert_eq!(inf.log2(), inf);
100+
assert!(neg_inf.log2().is_nan());
101+
assert!((-2.3f64).log2().is_nan());
102+
assert_eq!((-0.0f64).log2(), neg_inf);
103+
assert_eq!(0.0f64.log2(), neg_inf);
104+
}
105+
106+
#[test]
107+
fn test_log10() {
108+
let nan: f64 = f64::NAN;
109+
let inf: f64 = f64::INFINITY;
110+
let neg_inf: f64 = f64::NEG_INFINITY;
111+
assert_eq!(10.0f64.log10(), 1.0);
112+
assert_approx_eq!(2.3f64.log10(), 0.361728);
113+
assert_approx_eq!(1.0f64.exp().log10(), 0.434294);
114+
assert_eq!(1.0f64.log10(), 0.0);
115+
assert!(nan.log10().is_nan());
116+
assert_eq!(inf.log10(), inf);
117+
assert!(neg_inf.log10().is_nan());
118+
assert!((-2.3f64).log10().is_nan());
119+
assert_eq!((-0.0f64).log10(), neg_inf);
120+
assert_eq!(0.0f64.log10(), neg_inf);
121+
}
122+
123+
#[test]
124+
fn test_asinh() {
125+
assert_eq!(0.0f64.asinh(), 0.0f64);
126+
assert_eq!((-0.0f64).asinh(), -0.0f64);
127+
128+
let inf: f64 = f64::INFINITY;
129+
let neg_inf: f64 = f64::NEG_INFINITY;
130+
let nan: f64 = f64::NAN;
131+
assert_eq!(inf.asinh(), inf);
132+
assert_eq!(neg_inf.asinh(), neg_inf);
133+
assert!(nan.asinh().is_nan());
134+
assert!((-0.0f64).asinh().is_sign_negative());
135+
// issue 63271
136+
assert_approx_eq!(2.0f64.asinh(), 1.443635475178810342493276740273105f64);
137+
assert_approx_eq!((-2.0f64).asinh(), -1.443635475178810342493276740273105f64);
138+
// regression test for the catastrophic cancellation fixed in 72486
139+
assert_approx_eq!((-67452098.07139316f64).asinh(), -18.72007542627454439398548429400083);
140+
141+
// test for low accuracy from issue 104548
142+
assert_approx_eq!(60.0f64, 60.0f64.sinh().asinh());
143+
// mul needed for approximate comparison to be meaningful
144+
assert_approx_eq!(1.0f64, 1e-15f64.sinh().asinh() * 1e15f64);
145+
}
146+
147+
#[test]
148+
fn test_acosh() {
149+
assert_eq!(1.0f64.acosh(), 0.0f64);
150+
assert!(0.999f64.acosh().is_nan());
151+
152+
let inf: f64 = f64::INFINITY;
153+
let neg_inf: f64 = f64::NEG_INFINITY;
154+
let nan: f64 = f64::NAN;
155+
assert_eq!(inf.acosh(), inf);
156+
assert!(neg_inf.acosh().is_nan());
157+
assert!(nan.acosh().is_nan());
158+
assert_approx_eq!(2.0f64.acosh(), 1.31695789692481670862504634730796844f64);
159+
assert_approx_eq!(3.0f64.acosh(), 1.76274717403908605046521864995958461f64);
160+
161+
// test for low accuracy from issue 104548
162+
assert_approx_eq!(60.0f64, 60.0f64.cosh().acosh());
163+
}
164+
165+
#[test]
166+
fn test_atanh() {
167+
assert_eq!(0.0f64.atanh(), 0.0f64);
168+
assert_eq!((-0.0f64).atanh(), -0.0f64);
169+
170+
let inf: f64 = f64::INFINITY;
171+
let neg_inf: f64 = f64::NEG_INFINITY;
172+
let nan: f64 = f64::NAN;
173+
assert_eq!(1.0f64.atanh(), inf);
174+
assert_eq!((-1.0f64).atanh(), neg_inf);
175+
assert!(2f64.atanh().atanh().is_nan());
176+
assert!((-2f64).atanh().atanh().is_nan());
177+
assert!(inf.atanh().is_nan());
178+
assert!(neg_inf.atanh().is_nan());
179+
assert!(nan.atanh().is_nan());
180+
assert_approx_eq!(0.5f64.atanh(), 0.54930614433405484569762261846126285f64);
181+
assert_approx_eq!((-0.5f64).atanh(), -0.54930614433405484569762261846126285f64);
182+
}
183+
184+
#[test]
185+
fn test_gamma() {
186+
// precision can differ between platforms
187+
assert_approx_eq!(1.0f64.gamma(), 1.0f64);
188+
assert_approx_eq!(2.0f64.gamma(), 1.0f64);
189+
assert_approx_eq!(3.0f64.gamma(), 2.0f64);
190+
assert_approx_eq!(4.0f64.gamma(), 6.0f64);
191+
assert_approx_eq!(5.0f64.gamma(), 24.0f64);
192+
assert_approx_eq!(0.5f64.gamma(), consts::PI.sqrt());
193+
assert_approx_eq!((-0.5f64).gamma(), -2.0 * consts::PI.sqrt());
194+
assert_eq!(0.0f64.gamma(), f64::INFINITY);
195+
assert_eq!((-0.0f64).gamma(), f64::NEG_INFINITY);
196+
assert!((-1.0f64).gamma().is_nan());
197+
assert!((-2.0f64).gamma().is_nan());
198+
assert!(f64::NAN.gamma().is_nan());
199+
assert!(f64::NEG_INFINITY.gamma().is_nan());
200+
assert_eq!(f64::INFINITY.gamma(), f64::INFINITY);
201+
assert_eq!(171.71f64.gamma(), f64::INFINITY);
202+
}
203+
204+
#[test]
205+
fn test_ln_gamma() {
206+
assert_approx_eq!(1.0f64.ln_gamma().0, 0.0f64);
207+
assert_eq!(1.0f64.ln_gamma().1, 1);
208+
assert_approx_eq!(2.0f64.ln_gamma().0, 0.0f64);
209+
assert_eq!(2.0f64.ln_gamma().1, 1);
210+
assert_approx_eq!(3.0f64.ln_gamma().0, 2.0f64.ln());
211+
assert_eq!(3.0f64.ln_gamma().1, 1);
212+
assert_approx_eq!((-0.5f64).ln_gamma().0, (2.0 * consts::PI.sqrt()).ln());
213+
assert_eq!((-0.5f64).ln_gamma().1, -1);
214+
}
215+
216+
#[test]
217+
fn test_real_consts() {
218+
let pi: f64 = consts::PI;
219+
let frac_pi_2: f64 = consts::FRAC_PI_2;
220+
let frac_pi_3: f64 = consts::FRAC_PI_3;
221+
let frac_pi_4: f64 = consts::FRAC_PI_4;
222+
let frac_pi_6: f64 = consts::FRAC_PI_6;
223+
let frac_pi_8: f64 = consts::FRAC_PI_8;
224+
let frac_1_pi: f64 = consts::FRAC_1_PI;
225+
let frac_2_pi: f64 = consts::FRAC_2_PI;
226+
let frac_2_sqrtpi: f64 = consts::FRAC_2_SQRT_PI;
227+
let sqrt2: f64 = consts::SQRT_2;
228+
let frac_1_sqrt2: f64 = consts::FRAC_1_SQRT_2;
229+
let e: f64 = consts::E;
230+
let log2_e: f64 = consts::LOG2_E;
231+
let log10_e: f64 = consts::LOG10_E;
232+
let ln_2: f64 = consts::LN_2;
233+
let ln_10: f64 = consts::LN_10;
234+
235+
assert_approx_eq!(frac_pi_2, pi / 2f64);
236+
assert_approx_eq!(frac_pi_3, pi / 3f64);
237+
assert_approx_eq!(frac_pi_4, pi / 4f64);
238+
assert_approx_eq!(frac_pi_6, pi / 6f64);
239+
assert_approx_eq!(frac_pi_8, pi / 8f64);
240+
assert_approx_eq!(frac_1_pi, 1f64 / pi);
241+
assert_approx_eq!(frac_2_pi, 2f64 / pi);
242+
assert_approx_eq!(frac_2_sqrtpi, 2f64 / pi.sqrt());
243+
assert_approx_eq!(sqrt2, 2f64.sqrt());
244+
assert_approx_eq!(frac_1_sqrt2, 1f64 / 2f64.sqrt());
245+
assert_approx_eq!(log2_e, e.log2());
246+
assert_approx_eq!(log10_e, e.log10());
247+
assert_approx_eq!(ln_2, 2f64.ln());
248+
assert_approx_eq!(ln_10, 10f64.ln());
249+
}

‎library/std/tests/floats/lib.rs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#![feature(f16, f128, float_gamma, float_minimum_maximum)]
2+
3+
use std::fmt;
4+
use std::ops::{Add, Div, Mul, Rem, Sub};
5+
6+
/// Verify that floats are within a tolerance of each other, 1.0e-6 by default.
7+
macro_rules! assert_approx_eq {
8+
($a:expr, $b:expr) => {{ assert_approx_eq!($a, $b, 1.0e-6) }};
9+
($a:expr, $b:expr, $lim:expr) => {{
10+
let (a, b) = (&$a, &$b);
11+
let diff = (*a - *b).abs();
12+
assert!(
13+
diff < $lim,
14+
"{a:?} is not approximately equal to {b:?} (threshold {lim:?}, difference {diff:?})",
15+
lim = $lim
16+
);
17+
}};
18+
}
19+
20+
/// Helper function for testing numeric operations
21+
pub fn test_num<T>(ten: T, two: T)
22+
where
23+
T: PartialEq
24+
+ Add<Output = T>
25+
+ Sub<Output = T>
26+
+ Mul<Output = T>
27+
+ Div<Output = T>
28+
+ Rem<Output = T>
29+
+ fmt::Debug
30+
+ Copy,
31+
{
32+
assert_eq!(ten.add(two), ten + two);
33+
assert_eq!(ten.sub(two), ten - two);
34+
assert_eq!(ten.mul(two), ten * two);
35+
assert_eq!(ten.div(two), ten / two);
36+
assert_eq!(ten.rem(two), ten % two);
37+
}
38+
39+
mod f128;
40+
mod f16;
41+
mod f32;
42+
mod f64;

0 commit comments

Comments
 (0)
Please sign in to comment.