File tree Expand file tree Collapse file tree 4 files changed +32
-4
lines changed Expand file tree Collapse file tree 4 files changed +32
-4
lines changed Original file line number Diff line number Diff line change @@ -880,7 +880,9 @@ impl f32 {
880880 #[ stable( feature = "rust1" , since = "1.0.0" ) ]
881881 #[ inline]
882882 pub fn asinh ( self ) -> f32 {
883- ( self . abs ( ) + ( ( self * self ) + 1.0 ) . sqrt ( ) ) . ln ( ) . copysign ( self )
883+ let ax = self . abs ( ) ;
884+ let ix = 1.0 / ax;
885+ ( ax + ( ax / ( Self :: hypot ( 1.0 , ix) + ix) ) ) . ln_1p ( ) . copysign ( self )
884886 }
885887
886888 /// Inverse hyperbolic cosine function.
@@ -900,7 +902,11 @@ impl f32 {
900902 #[ stable( feature = "rust1" , since = "1.0.0" ) ]
901903 #[ inline]
902904 pub fn acosh ( self ) -> f32 {
903- if self < 1.0 { Self :: NAN } else { ( self + ( ( self * self ) - 1.0 ) . sqrt ( ) ) . ln ( ) }
905+ if self < 1.0 {
906+ Self :: NAN
907+ } else {
908+ ( self + ( ( self - 1.0 ) . sqrt ( ) * ( self + 1.0 ) . sqrt ( ) ) ) . ln ( )
909+ }
904910 }
905911
906912 /// Inverse hyperbolic tangent function.
Original file line number Diff line number Diff line change @@ -587,6 +587,11 @@ fn test_asinh() {
587587 assert_approx_eq ! ( ( -2.0f32 ) . asinh( ) , -1.443635475178810342493276740273105f32 ) ;
588588 // regression test for the catastrophic cancellation fixed in 72486
589589 assert_approx_eq ! ( ( -3000.0f32 ) . asinh( ) , -8.699514775987968673236893537700647f32 ) ;
590+
591+ // test for low accuracy from issue 104548
592+ assert_approx_eq ! ( 60.0f32 , 60.0f32 . sinh( ) . asinh( ) ) ;
593+ // mul needed for approximate comparison to be meaningful
594+ assert_approx_eq ! ( 1.0f32 , 1e-15f32 . sinh( ) . asinh( ) * 1e15f32 ) ;
590595}
591596
592597#[ test]
@@ -602,6 +607,9 @@ fn test_acosh() {
602607 assert ! ( nan. acosh( ) . is_nan( ) ) ;
603608 assert_approx_eq ! ( 2.0f32 . acosh( ) , 1.31695789692481670862504634730796844f32 ) ;
604609 assert_approx_eq ! ( 3.0f32 . acosh( ) , 1.76274717403908605046521864995958461f32 ) ;
610+
611+ // test for low accuracy from issue 104548
612+ assert_approx_eq ! ( 60.0f32 , 60.0f32 . cosh( ) . acosh( ) ) ;
605613}
606614
607615#[ test]
Original file line number Diff line number Diff line change @@ -882,7 +882,9 @@ impl f64 {
882882 #[ stable( feature = "rust1" , since = "1.0.0" ) ]
883883 #[ inline]
884884 pub fn asinh ( self ) -> f64 {
885- ( self . abs ( ) + ( ( self * self ) + 1.0 ) . sqrt ( ) ) . ln ( ) . copysign ( self )
885+ let ax = self . abs ( ) ;
886+ let ix = 1.0 / ax;
887+ ( ax + ( ax / ( Self :: hypot ( 1.0 , ix) + ix) ) ) . ln_1p ( ) . copysign ( self )
886888 }
887889
888890 /// Inverse hyperbolic cosine function.
@@ -902,7 +904,11 @@ impl f64 {
902904 #[ stable( feature = "rust1" , since = "1.0.0" ) ]
903905 #[ inline]
904906 pub fn acosh ( self ) -> f64 {
905- if self < 1.0 { Self :: NAN } else { ( self + ( ( self * self ) - 1.0 ) . sqrt ( ) ) . ln ( ) }
907+ if self < 1.0 {
908+ Self :: NAN
909+ } else {
910+ ( self + ( ( self - 1.0 ) . sqrt ( ) * ( self + 1.0 ) . sqrt ( ) ) ) . ln ( )
911+ }
906912 }
907913
908914 /// Inverse hyperbolic tangent function.
Original file line number Diff line number Diff line change @@ -575,6 +575,11 @@ fn test_asinh() {
575575 assert_approx_eq ! ( ( -2.0f64 ) . asinh( ) , -1.443635475178810342493276740273105f64 ) ;
576576 // regression test for the catastrophic cancellation fixed in 72486
577577 assert_approx_eq ! ( ( -67452098.07139316f64 ) . asinh( ) , -18.72007542627454439398548429400083 ) ;
578+
579+ // test for low accuracy from issue 104548
580+ assert_approx_eq ! ( 60.0f64 , 60.0f64 . sinh( ) . asinh( ) ) ;
581+ // mul needed for approximate comparison to be meaningful
582+ assert_approx_eq ! ( 1.0f64 , 1e-15f64 . sinh( ) . asinh( ) * 1e15f64 ) ;
578583}
579584
580585#[ test]
@@ -590,6 +595,9 @@ fn test_acosh() {
590595 assert ! ( nan. acosh( ) . is_nan( ) ) ;
591596 assert_approx_eq ! ( 2.0f64 . acosh( ) , 1.31695789692481670862504634730796844f64 ) ;
592597 assert_approx_eq ! ( 3.0f64 . acosh( ) , 1.76274717403908605046521864995958461f64 ) ;
598+
599+ // test for low accuracy from issue 104548
600+ assert_approx_eq ! ( 60.0f64 , 60.0f64 . cosh( ) . acosh( ) ) ;
593601}
594602
595603#[ test]
You can’t perform that action at this time.
0 commit comments