Skip to content

Commit 5a57f24

Browse files
committed
Add ln_gamma function to f32 and f64
1 parent f05c188 commit 5a57f24

File tree

6 files changed

+73
-1
lines changed

6 files changed

+73
-1
lines changed

library/std/src/f32.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -978,4 +978,26 @@ impl f32 {
978978
pub fn gamma(self) -> f32 {
979979
unsafe { cmath::tgammaf(self) }
980980
}
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+
}
9811003
}

library/std/src/f32/tests.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -671,6 +671,18 @@ fn test_gamma() {
671671
assert_eq!(171.71f32.gamma(), f32::INFINITY);
672672
}
673673

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+
674686
#[test]
675687
fn test_real_consts() {
676688
use super::consts;

library/std/src/f64.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1004,4 +1004,26 @@ impl f64 {
10041004
pub fn gamma(self) -> f64 {
10051005
unsafe { cmath::tgamma(self) }
10061006
}
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+
}
10071029
}

library/std/src/f64/tests.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -654,6 +654,18 @@ fn test_gamma() {
654654
assert_eq!(171.71f64.gamma(), f64::INFINITY);
655655
}
656656

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+
657669
#[test]
658670
fn test_real_consts() {
659671
use super::consts;

library/std/src/sys/unix/cmath.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,6 @@ extern "C" {
3232
pub fn tanhf(n: f32) -> f32;
3333
pub fn tgamma(n: f64) -> f64;
3434
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;
3537
}

library/std/src/sys/windows/cmath.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#![cfg(not(test))]
22

3-
use libc::{c_double, c_float};
3+
use libc::{c_double, c_float, c_int};
44

55
extern "C" {
66
pub fn acos(n: c_double) -> c_double;
@@ -25,6 +25,8 @@ extern "C" {
2525
pub fn tanh(n: c_double) -> c_double;
2626
pub fn tgamma(n: c_double) -> c_double;
2727
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;
2830
}
2931

3032
pub use self::shims::*;

0 commit comments

Comments
 (0)