@@ -2,7 +2,11 @@ use crate::f16::consts;
22use  crate :: num:: FpCategory  as  Fp ; 
33use  crate :: num:: * ; 
44
5- const  F16_APPROX :  f16  = 0.001 ; 
5+ // We run out of precision pretty quickly with f16 
6+ const  F16_APPROX_L1 :  f16  = 0.001 ; 
7+ const  F16_APPROX_L2 :  f16  = 0.01 ; 
8+ const  F16_APPROX_L3 :  f16  = 0.1 ; 
9+ const  F16_APPROX_L4 :  f16  = 0.5 ; 
610
711#[ test]  
812fn  test_num_f16 ( )  { 
@@ -160,8 +164,8 @@ fn test_is_normal() {
160164    assert ! ( !zero. is_normal( ) ) ; 
161165    assert ! ( !neg_zero. is_normal( ) ) ; 
162166    assert ! ( 1 f16. is_normal( ) ) ; 
163-     assert ! ( 1e-37f16  . is_normal( ) ) ; 
164-     assert ! ( !1e-38f16  . is_normal( ) ) ; 
167+     assert ! ( 1e-4f16  . is_normal( ) ) ; 
168+     assert ! ( !1e-5f16  . is_normal( ) ) ; 
165169} 
166170
167171#[ test]  
@@ -177,8 +181,8 @@ fn test_classify() {
177181    assert_eq ! ( zero. classify( ) ,  Fp :: Zero ) ; 
178182    assert_eq ! ( neg_zero. classify( ) ,  Fp :: Zero ) ; 
179183    assert_eq ! ( 1 f16. classify( ) ,  Fp :: Normal ) ; 
180-     assert_eq ! ( 1e-37f16  . classify( ) ,  Fp :: Normal ) ; 
181-     assert_eq ! ( 1e-38f16  . classify( ) ,  Fp :: Subnormal ) ; 
184+     assert_eq ! ( 1e-4f16  . classify( ) ,  Fp :: Normal ) ; 
185+     assert_eq ! ( 1e-5f16  . classify( ) ,  Fp :: Subnormal ) ; 
182186} 
183187
184188#[ test]  
@@ -255,16 +259,16 @@ fn test_trunc() {
255259
256260#[ test]  
257261fn  test_fract ( )  { 
258-     assert_approx_eq ! ( 1.0f16 . fract( ) ,  0.0f16 ,  F16_APPROX ) ; 
259-     assert_approx_eq ! ( 1.3f16 . fract( ) ,  0.3f16 ,  F16_APPROX ) ; 
260-     assert_approx_eq ! ( 1.5f16 . fract( ) ,  0.5f16 ,  F16_APPROX ) ; 
261-     assert_approx_eq ! ( 1.7f16 . fract( ) ,  0.7f16 ,  F16_APPROX ) ; 
262-     assert_approx_eq ! ( 0.0f16 . fract( ) ,  0.0f16 ,  F16_APPROX ) ; 
263-     assert_approx_eq ! ( ( -0.0f16 ) . fract( ) ,  -0.0f16 ,  F16_APPROX ) ; 
264-     assert_approx_eq ! ( ( -1.0f16 ) . fract( ) ,  -0.0f16 ,  F16_APPROX ) ; 
265-     assert_approx_eq ! ( ( -1.3f16 ) . fract( ) ,  -0.3f16 ,  F16_APPROX ) ; 
266-     assert_approx_eq ! ( ( -1.5f16 ) . fract( ) ,  -0.5f16 ,  F16_APPROX ) ; 
267-     assert_approx_eq ! ( ( -1.7f16 ) . fract( ) ,  -0.7f16 ,  F16_APPROX ) ; 
262+     assert_approx_eq ! ( 1.0f16 . fract( ) ,  0.0f16 ,  F16_APPROX_L1 ) ; 
263+     assert_approx_eq ! ( 1.3f16 . fract( ) ,  0.3f16 ,  F16_APPROX_L1 ) ; 
264+     assert_approx_eq ! ( 1.5f16 . fract( ) ,  0.5f16 ,  F16_APPROX_L1 ) ; 
265+     assert_approx_eq ! ( 1.7f16 . fract( ) ,  0.7f16 ,  F16_APPROX_L1 ) ; 
266+     assert_approx_eq ! ( 0.0f16 . fract( ) ,  0.0f16 ,  F16_APPROX_L1 ) ; 
267+     assert_approx_eq ! ( ( -0.0f16 ) . fract( ) ,  -0.0f16 ,  F16_APPROX_L1 ) ; 
268+     assert_approx_eq ! ( ( -1.0f16 ) . fract( ) ,  -0.0f16 ,  F16_APPROX_L1 ) ; 
269+     assert_approx_eq ! ( ( -1.3f16 ) . fract( ) ,  -0.3f16 ,  F16_APPROX_L1 ) ; 
270+     assert_approx_eq ! ( ( -1.5f16 ) . fract( ) ,  -0.5f16 ,  F16_APPROX_L1 ) ; 
271+     assert_approx_eq ! ( ( -1.7f16 ) . fract( ) ,  -0.7f16 ,  F16_APPROX_L1 ) ; 
268272} 
269273
270274#[ test]  
@@ -402,10 +406,10 @@ fn test_mul_add() {
402406    let  nan:  f16  = f16:: NAN ; 
403407    let  inf:  f16  = f16:: INFINITY ; 
404408    let  neg_inf:  f16  = f16:: NEG_INFINITY ; 
405-     assert_approx_eq ! ( 12.3f16 . mul_add( 4.5 ,  6.7 ) ,  62.05 ,  F16_APPROX ) ; 
406-     assert_approx_eq ! ( ( -12.3f16 ) . mul_add( -4.5 ,  -6.7 ) ,  48.65 ,  F16_APPROX ) ; 
407-     assert_approx_eq ! ( 0.0f16 . mul_add( 8.9 ,  1.2 ) ,  1.2 ,  F16_APPROX ) ; 
408-     assert_approx_eq ! ( 3.4f16 . mul_add( -0.0 ,  5.6 ) ,  5.6 ,  F16_APPROX ) ; 
409+     assert_approx_eq ! ( 12.3f16 . mul_add( 4.5 ,  6.7 ) ,  62.05 ,  F16_APPROX_L3 ) ; 
410+     assert_approx_eq ! ( ( -12.3f16 ) . mul_add( -4.5 ,  -6.7 ) ,  48.65 ,  F16_APPROX_L4 ) ; 
411+     assert_approx_eq ! ( 0.0f16 . mul_add( 8.9 ,  1.2 ) ,  1.2 ,  F16_APPROX_L2 ) ; 
412+     assert_approx_eq ! ( 3.4f16 . mul_add( -0.0 ,  5.6 ) ,  5.6 ,  F16_APPROX_L2 ) ; 
409413    assert ! ( nan. mul_add( 7.8 ,  9.0 ) . is_nan( ) ) ; 
410414    assert_eq ! ( inf. mul_add( 7.8 ,  9.0 ) ,  inf) ; 
411415    assert_eq ! ( neg_inf. mul_add( 7.8 ,  9.0 ) ,  neg_inf) ; 
@@ -427,48 +431,35 @@ fn test_recip() {
427431    assert_eq ! ( neg_inf. recip( ) ,  0.0 ) ; 
428432} 
429433
430- // TODO: powi gives me LLVM errors: 
431- //  
432- // Both operands to a binary operator are not of the same type! 
433- //   %10 = fadd float %9, half 0xHC8CE 
434- // Call parameter type does not match function signature! 
435- //   %10 = fadd float %9, half 0xHC8CE 
436- //  half  %11 = tail call half @llvm.fabs.f16(float %10) 
437- // Intrinsic has incorrect argument type! 
438- // ptr @llvm.powi.f16 
439- // in function _ZN3std3f165tests9test_powi17h5053d7d11c8cb05dE 
440- // LLVM ERROR: Broken function found, compilation aborted! 
441- //  
442- // #[test] 
443- // fn test_powi() { 
444- //     let nan: f16 = f16::NAN; 
445- //     let inf: f16 = f16::INFINITY; 
446- //     let neg_inf: f16 = f16::NEG_INFINITY; 
447- //     assert_eq!(1.0f16.powi(1), 1.0); 
448- //     assert_approx_eq!((-3.1f16).powi(2), 9.61); 
449- //     assert_approx_eq!(5.9f16.powi(-2), 0.028727); 
450- //     assert_eq!(8.3f16.powi(0), 1.0); 
451- //     assert!(nan.powi(2).is_nan()); 
452- //     assert_eq!(inf.powi(3), inf); 
453- //     assert_eq!(neg_inf.powi(2), inf); 
454- // } 
434+ #[ test]  
435+ fn  test_powi ( )  { 
436+     let  nan:  f16  = f16:: NAN ; 
437+     let  inf:  f16  = f16:: INFINITY ; 
438+     let  neg_inf:  f16  = f16:: NEG_INFINITY ; 
439+     assert_eq ! ( 1.0f16 . powi( 1 ) ,  1.0 ) ; 
440+     assert_approx_eq ! ( ( -3.1f16 ) . powi( 2 ) ,  9.61 ) ; 
441+     assert_approx_eq ! ( 5.9f16 . powi( -2 ) ,  0.028727 ) ; 
442+     assert_eq ! ( 8.3f16 . powi( 0 ) ,  1.0 ) ; 
443+     assert ! ( nan. powi( 2 ) . is_nan( ) ) ; 
444+     assert_eq ! ( inf. powi( 3 ) ,  inf) ; 
445+     assert_eq ! ( neg_inf. powi( 2 ) ,  inf) ; 
446+ } 
455447
456- // TODO: LLVM errors 
457- // #[test] 
458- // fn test_powf() { 
459- //     let nan: f16 = f16::NAN; 
460- //     let inf: f16 = f16::INFINITY; 
461- //     let neg_inf: f16 = f16::NEG_INFINITY; 
462- //     assert_eq!(1.0f16.powf(1.0), 1.0); 
463- //     assert_approx_eq!(3.4f16.powf(4.5), 246.408218); 
464- //     assert_approx_eq!(2.7f16.powf(-3.2), 0.041652); 
465- //     assert_approx_eq!((-3.1f16).powf(2.0), 9.61); 
466- //     assert_approx_eq!(5.9f16.powf(-2.0), 0.028727); 
467- //     assert_eq!(8.3f16.powf(0.0), 1.0); 
468- //     assert!(nan.powf(2.0).is_nan()); 
469- //     assert_eq!(inf.powf(2.0), inf); 
470- //     assert_eq!(neg_inf.powf(3.0), neg_inf); 
471- // } 
448+ #[ test]  
449+ fn  test_powf ( )  { 
450+     let  nan:  f16  = f16:: NAN ; 
451+     let  inf:  f16  = f16:: INFINITY ; 
452+     let  neg_inf:  f16  = f16:: NEG_INFINITY ; 
453+     assert_eq ! ( 1.0f16 . powf( 1.0 ) ,  1.0 ) ; 
454+     assert_approx_eq ! ( 3.4f16 . powf( 4.5 ) ,  246.408218 ,  F16_APPROX_L4 ) ; 
455+     assert_approx_eq ! ( 2.7f16 . powf( -3.2 ) ,  0.041652 ,  F16_APPROX_L1 ) ; 
456+     assert_approx_eq ! ( ( -3.1f16 ) . powf( 2.0 ) ,  9.61 ,  F16_APPROX_L1 ) ; 
457+     assert_approx_eq ! ( 5.9f16 . powf( -2.0 ) ,  0.028727 ,  F16_APPROX_L1 ) ; 
458+     assert_eq ! ( 8.3f16 . powf( 0.0 ) ,  1.0 ) ; 
459+     assert ! ( nan. powf( 2.0 ) . is_nan( ) ) ; 
460+     assert_eq ! ( inf. powf( 2.0 ) ,  inf) ; 
461+     assert_eq ! ( neg_inf. powf( 3.0 ) ,  neg_inf) ; 
462+ } 
472463
473464#[ test]  
474465fn  test_sqrt_domain ( )  { 
@@ -546,9 +537,9 @@ fn test_log2() {
546537    let  nan:  f16  = f16:: NAN ; 
547538    let  inf:  f16  = f16:: INFINITY ; 
548539    let  neg_inf:  f16  = f16:: NEG_INFINITY ; 
549-     assert_approx_eq ! ( 10.0f16 . log2( ) ,  3.321928 ,  F16_APPROX ) ; 
550-     assert_approx_eq ! ( 2.3f16 . log2( ) ,  1.201634 ,  F16_APPROX ) ; 
551-     assert_approx_eq ! ( 1.0f16 . exp( ) . log2( ) ,  1.442695 ,  F16_APPROX ) ; 
540+     assert_approx_eq ! ( 10.0f16 . log2( ) ,  3.321928 ,  F16_APPROX_L1 ) ; 
541+     assert_approx_eq ! ( 2.3f16 . log2( ) ,  1.201634 ,  F16_APPROX_L1 ) ; 
542+     assert_approx_eq ! ( 1.0f16 . exp( ) . log2( ) ,  1.442695 ,  F16_APPROX_L1 ) ; 
552543    assert ! ( nan. log2( ) . is_nan( ) ) ; 
553544    assert_eq ! ( inf. log2( ) ,  inf) ; 
554545    assert ! ( neg_inf. log2( ) . is_nan( ) ) ; 
@@ -581,13 +572,12 @@ fn test_to_degrees() {
581572    let  inf:  f16  = f16:: INFINITY ; 
582573    let  neg_inf:  f16  = f16:: NEG_INFINITY ; 
583574    assert_eq ! ( 0.0f16 . to_degrees( ) ,  0.0 ) ; 
584-     // Loss of precision here, increase our bounds 
585-     assert_approx_eq ! ( ( -5.8f16 ) . to_degrees( ) ,  -332.315521 ,  F16_APPROX  *  1.1 ) ; 
575+     assert_approx_eq ! ( ( -5.8f16 ) . to_degrees( ) ,  -332.315521 ,  F16_APPROX_L4 ) ; 
586576    assert_eq ! ( pi. to_degrees( ) ,  180.0 ) ; 
587577    assert ! ( nan. to_degrees( ) . is_nan( ) ) ; 
588578    assert_eq ! ( inf. to_degrees( ) ,  inf) ; 
589579    assert_eq ! ( neg_inf. to_degrees( ) ,  neg_inf) ; 
590-     assert_eq ! ( 1_ f16. to_degrees( ) ,  57.2957795130823208767981548141051703  ) ; 
580+     assert_approx_eq ! ( 1_ f16. to_degrees( ) ,  57.29577951  ,   F16_APPROX_L3 ) ; 
591581} 
592582
593583#[ test]  
@@ -597,15 +587,15 @@ fn test_to_radians() {
597587    let  inf:  f16  = f16:: INFINITY ; 
598588    let  neg_inf:  f16  = f16:: NEG_INFINITY ; 
599589    assert_eq ! ( 0.0f16 . to_radians( ) ,  0.0 ) ; 
600-     // Loss of precision here, increase our bounds 
601-     assert_approx_eq ! ( 154.6f16 . to_radians( ) ,  2.698279 ,  F16_APPROX  *  1.1 ) ; 
602-     assert_approx_eq ! ( ( -332.31f16 ) . to_radians( ) ,  -5.799903 ,  F16_APPROX ) ; 
603-     assert_eq ! ( 180.0f16 . to_radians( ) ,  pi) ; 
590+     assert_approx_eq ! ( 154.6f16 . to_radians( ) ,  2.698279 ,  F16_APPROX_L3 ) ; 
591+     assert_approx_eq ! ( ( -332.31f16 ) . to_radians( ) ,  -5.799903 ,  F16_APPROX_L3 ) ; 
592+     assert_approx_eq ! ( 180.0f16 . to_radians( ) ,  pi,  F16_APPROX_L3 ) ; 
604593    assert ! ( nan. to_radians( ) . is_nan( ) ) ; 
605594    assert_eq ! ( inf. to_radians( ) ,  inf) ; 
606595    assert_eq ! ( neg_inf. to_radians( ) ,  neg_inf) ; 
607596} 
608597
598+ // Disabled since this relies on cmath 
609599// #[test] 
610600// fn test_asinh() { 
611601//     assert_eq!(0.0f16.asinh(), 0.0f16); 
@@ -724,20 +714,20 @@ fn test_real_consts() {
724714    let  ln_2:  f16  = consts:: LN_2 ; 
725715    let  ln_10:  f16  = consts:: LN_10 ; 
726716
727-     assert_approx_eq ! ( frac_pi_2,  pi / 2 f16,  F16_APPROX ) ; 
728-     assert_approx_eq ! ( frac_pi_3,  pi / 3 f16,  F16_APPROX ) ; 
729-     assert_approx_eq ! ( frac_pi_4,  pi / 4 f16,  F16_APPROX ) ; 
730-     assert_approx_eq ! ( frac_pi_6,  pi / 6 f16,  F16_APPROX ) ; 
731-     assert_approx_eq ! ( frac_pi_8,  pi / 8 f16,  F16_APPROX ) ; 
732-     assert_approx_eq ! ( frac_1_pi,  1 f16 / pi,  F16_APPROX ) ; 
733-     assert_approx_eq ! ( frac_2_pi,  2 f16 / pi,  F16_APPROX ) ; 
734-     assert_approx_eq ! ( frac_2_sqrtpi,  2 f16 / pi. sqrt( ) ,  F16_APPROX ) ; 
735-     assert_approx_eq ! ( sqrt2,  2 f16. sqrt( ) ,  F16_APPROX ) ; 
736-     assert_approx_eq ! ( frac_1_sqrt2,  1 f16 / 2 f16. sqrt( ) ,  F16_APPROX ) ; 
737-     assert_approx_eq ! ( log2_e,  e. log2( ) ,  F16_APPROX ) ; 
738-     assert_approx_eq ! ( log10_e,  e. log10( ) ,  F16_APPROX ) ; 
739-     assert_approx_eq ! ( ln_2,  2 f16. ln( ) ,  F16_APPROX ) ; 
740-     assert_approx_eq ! ( ln_10,  10 f16. ln( ) ,  F16_APPROX ) ; 
717+     assert_approx_eq ! ( frac_pi_2,  pi / 2 f16,  F16_APPROX_L1 ) ; 
718+     assert_approx_eq ! ( frac_pi_3,  pi / 3 f16,  F16_APPROX_L1 ) ; 
719+     assert_approx_eq ! ( frac_pi_4,  pi / 4 f16,  F16_APPROX_L1 ) ; 
720+     assert_approx_eq ! ( frac_pi_6,  pi / 6 f16,  F16_APPROX_L1 ) ; 
721+     assert_approx_eq ! ( frac_pi_8,  pi / 8 f16,  F16_APPROX_L1 ) ; 
722+     assert_approx_eq ! ( frac_1_pi,  1 f16 / pi,  F16_APPROX_L1 ) ; 
723+     assert_approx_eq ! ( frac_2_pi,  2 f16 / pi,  F16_APPROX_L1 ) ; 
724+     assert_approx_eq ! ( frac_2_sqrtpi,  2 f16 / pi. sqrt( ) ,  F16_APPROX_L1 ) ; 
725+     assert_approx_eq ! ( sqrt2,  2 f16. sqrt( ) ,  F16_APPROX_L1 ) ; 
726+     assert_approx_eq ! ( frac_1_sqrt2,  1 f16 / 2 f16. sqrt( ) ,  F16_APPROX_L1 ) ; 
727+     assert_approx_eq ! ( log2_e,  e. log2( ) ,  F16_APPROX_L1 ) ; 
728+     assert_approx_eq ! ( log10_e,  e. log10( ) ,  F16_APPROX_L1 ) ; 
729+     assert_approx_eq ! ( ln_2,  2 f16. ln( ) ,  F16_APPROX_L1 ) ; 
730+     assert_approx_eq ! ( ln_10,  10 f16. ln( ) ,  F16_APPROX_L1 ) ; 
741731} 
742732
743733#[ test]  
0 commit comments