File tree 6 files changed +73
-1
lines changed 6 files changed +73
-1
lines changed Original file line number Diff line number Diff line change @@ -978,4 +978,26 @@ impl f32 {
978
978
pub fn gamma ( self ) -> f32 {
979
979
unsafe { cmath:: tgammaf ( self ) }
980
980
}
981
+
982
+ /// Returns the natural logarithm of the gamma function.
983
+ ///
984
+ /// # Examples
985
+ ///
986
+ /// ```
987
+ /// #![feature(float_gamma)]
988
+ /// let x = 2.0f32;
989
+ ///
990
+ /// let abs_difference = (x.ln_gamma().0 - 0.0).abs();
991
+ ///
992
+ /// assert!(abs_difference <= f32::EPSILON);
993
+ /// ```
994
+ #[ rustc_allow_incoherent_impl]
995
+ #[ must_use = "method returns a new number and does not mutate the original value" ]
996
+ #[ unstable( feature = "float_gamma" , issue = "99842" ) ]
997
+ #[ inline]
998
+ pub fn ln_gamma ( self ) -> ( f32 , i32 ) {
999
+ let mut signgamp: i32 = 0 ;
1000
+ let x = unsafe { cmath:: lgammaf_r ( self , & mut signgamp) } ;
1001
+ ( x, signgamp)
1002
+ }
981
1003
}
Original file line number Diff line number Diff line change @@ -671,6 +671,18 @@ fn test_gamma() {
671
671
assert_eq ! ( 171.71f32 . gamma( ) , f32 :: INFINITY ) ;
672
672
}
673
673
674
+ #[ test]
675
+ fn test_ln_gamma ( ) {
676
+ assert_approx_eq ! ( 1.0f32 . ln_gamma( ) . 0 , 0.0f32 ) ;
677
+ assert_eq ! ( 1.0f32 . ln_gamma( ) . 1 , 1 ) ;
678
+ assert_approx_eq ! ( 2.0f32 . ln_gamma( ) . 0 , 0.0f32 ) ;
679
+ assert_eq ! ( 2.0f32 . ln_gamma( ) . 1 , 1 ) ;
680
+ assert_approx_eq ! ( 3.0f32 . ln_gamma( ) . 0 , 2.0f32 . ln( ) ) ;
681
+ assert_eq ! ( 3.0f32 . ln_gamma( ) . 1 , 1 ) ;
682
+ assert_approx_eq ! ( ( -0.5f32 ) . ln_gamma( ) . 0 , ( 2.0 * consts:: PI . sqrt( ) ) . ln( ) ) ;
683
+ assert_eq ! ( ( -0.5f32 ) . ln_gamma( ) . 1 , -1 ) ;
684
+ }
685
+
674
686
#[ test]
675
687
fn test_real_consts ( ) {
676
688
use super :: consts;
Original file line number Diff line number Diff line change @@ -1004,4 +1004,26 @@ impl f64 {
1004
1004
pub fn gamma ( self ) -> f64 {
1005
1005
unsafe { cmath:: tgamma ( self ) }
1006
1006
}
1007
+
1008
+ /// Returns the natural logarithm of the gamma function.
1009
+ ///
1010
+ /// # Examples
1011
+ ///
1012
+ /// ```
1013
+ /// #![feature(float_gamma)]
1014
+ /// let x = 2.0f64;
1015
+ ///
1016
+ /// let abs_difference = (x.ln_gamma().0 - 0.0).abs();
1017
+ ///
1018
+ /// assert!(abs_difference <= f64::EPSILON);
1019
+ /// ```
1020
+ #[ rustc_allow_incoherent_impl]
1021
+ #[ must_use = "method returns a new number and does not mutate the original value" ]
1022
+ #[ unstable( feature = "float_gamma" , issue = "99842" ) ]
1023
+ #[ inline]
1024
+ pub fn ln_gamma ( self ) -> ( f64 , i32 ) {
1025
+ let mut signgamp: i32 = 0 ;
1026
+ let x = unsafe { cmath:: lgamma_r ( self , & mut signgamp) } ;
1027
+ ( x, signgamp)
1028
+ }
1007
1029
}
Original file line number Diff line number Diff line change @@ -654,6 +654,18 @@ fn test_gamma() {
654
654
assert_eq ! ( 171.71f64 . gamma( ) , f64 :: INFINITY ) ;
655
655
}
656
656
657
+ #[ test]
658
+ fn test_ln_gamma ( ) {
659
+ assert_approx_eq ! ( 1.0f64 . ln_gamma( ) . 0 , 0.0f64 ) ;
660
+ assert_eq ! ( 1.0f64 . ln_gamma( ) . 1 , 1 ) ;
661
+ assert_approx_eq ! ( 2.0f64 . ln_gamma( ) . 0 , 0.0f64 ) ;
662
+ assert_eq ! ( 2.0f64 . ln_gamma( ) . 1 , 1 ) ;
663
+ assert_approx_eq ! ( 3.0f64 . ln_gamma( ) . 0 , 2.0f64 . ln( ) ) ;
664
+ assert_eq ! ( 3.0f64 . ln_gamma( ) . 1 , 1 ) ;
665
+ assert_approx_eq ! ( ( -0.5f64 ) . ln_gamma( ) . 0 , ( 2.0 * consts:: PI . sqrt( ) ) . ln( ) ) ;
666
+ assert_eq ! ( ( -0.5f64 ) . ln_gamma( ) . 1 , -1 ) ;
667
+ }
668
+
657
669
#[ test]
658
670
fn test_real_consts ( ) {
659
671
use super :: consts;
Original file line number Diff line number Diff line change @@ -32,4 +32,6 @@ extern "C" {
32
32
pub fn tanhf ( n : f32 ) -> f32 ;
33
33
pub fn tgamma ( n : f64 ) -> f64 ;
34
34
pub fn tgammaf ( n : f32 ) -> f32 ;
35
+ pub fn lgamma_r ( n : f64 , s : & mut i32 ) -> f64 ;
36
+ pub fn lgammaf_r ( n : f32 , s : & mut i32 ) -> f32 ;
35
37
}
Original file line number Diff line number Diff line change 1
1
#![ cfg( not( test) ) ]
2
2
3
- use libc:: { c_double, c_float} ;
3
+ use libc:: { c_double, c_float, c_int } ;
4
4
5
5
extern "C" {
6
6
pub fn acos ( n : c_double ) -> c_double ;
@@ -25,6 +25,8 @@ extern "C" {
25
25
pub fn tanh ( n : c_double ) -> c_double ;
26
26
pub fn tgamma ( n : c_double ) -> c_double ;
27
27
pub fn tgammaf ( n : c_float ) -> c_float ;
28
+ pub fn lgamma_r ( n : c_double , s : & mut c_int ) -> c_double ;
29
+ pub fn lgammaf_r ( n : c_float , s : & mut c_int ) -> c_float ;
28
30
}
29
31
30
32
pub use self :: shims:: * ;
You can’t perform that action at this time.
0 commit comments