Skip to content

Commit

Permalink
Add ln_gamma function to f32 and f64
Browse files Browse the repository at this point in the history
  • Loading branch information
ankane committed Apr 12, 2023
1 parent f05c188 commit 5a57f24
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 1 deletion.
22 changes: 22 additions & 0 deletions library/std/src/f32.rs
Original file line number Diff line number Diff line change
Expand Up @@ -978,4 +978,26 @@ impl f32 {
pub fn gamma(self) -> f32 {
unsafe { cmath::tgammaf(self) }
}

/// Returns the natural logarithm of the gamma function.
///
/// # Examples
///
/// ```
/// #![feature(float_gamma)]
/// let x = 2.0f32;
///
/// let abs_difference = (x.ln_gamma().0 - 0.0).abs();
///
/// assert!(abs_difference <= f32::EPSILON);
/// ```
#[rustc_allow_incoherent_impl]
#[must_use = "method returns a new number and does not mutate the original value"]
#[unstable(feature = "float_gamma", issue = "99842")]
#[inline]
pub fn ln_gamma(self) -> (f32, i32) {
let mut signgamp: i32 = 0;
let x = unsafe { cmath::lgammaf_r(self, &mut signgamp) };
(x, signgamp)
}
}
12 changes: 12 additions & 0 deletions library/std/src/f32/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -671,6 +671,18 @@ fn test_gamma() {
assert_eq!(171.71f32.gamma(), f32::INFINITY);
}

#[test]
fn test_ln_gamma() {
assert_approx_eq!(1.0f32.ln_gamma().0, 0.0f32);
assert_eq!(1.0f32.ln_gamma().1, 1);
assert_approx_eq!(2.0f32.ln_gamma().0, 0.0f32);
assert_eq!(2.0f32.ln_gamma().1, 1);
assert_approx_eq!(3.0f32.ln_gamma().0, 2.0f32.ln());
assert_eq!(3.0f32.ln_gamma().1, 1);
assert_approx_eq!((-0.5f32).ln_gamma().0, (2.0 * consts::PI.sqrt()).ln());
assert_eq!((-0.5f32).ln_gamma().1, -1);
}

#[test]
fn test_real_consts() {
use super::consts;
Expand Down
22 changes: 22 additions & 0 deletions library/std/src/f64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1004,4 +1004,26 @@ impl f64 {
pub fn gamma(self) -> f64 {
unsafe { cmath::tgamma(self) }
}

/// Returns the natural logarithm of the gamma function.
///
/// # Examples
///
/// ```
/// #![feature(float_gamma)]
/// let x = 2.0f64;
///
/// let abs_difference = (x.ln_gamma().0 - 0.0).abs();
///
/// assert!(abs_difference <= f64::EPSILON);
/// ```
#[rustc_allow_incoherent_impl]
#[must_use = "method returns a new number and does not mutate the original value"]
#[unstable(feature = "float_gamma", issue = "99842")]
#[inline]
pub fn ln_gamma(self) -> (f64, i32) {
let mut signgamp: i32 = 0;
let x = unsafe { cmath::lgamma_r(self, &mut signgamp) };
(x, signgamp)
}
}
12 changes: 12 additions & 0 deletions library/std/src/f64/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -654,6 +654,18 @@ fn test_gamma() {
assert_eq!(171.71f64.gamma(), f64::INFINITY);
}

#[test]
fn test_ln_gamma() {
assert_approx_eq!(1.0f64.ln_gamma().0, 0.0f64);
assert_eq!(1.0f64.ln_gamma().1, 1);
assert_approx_eq!(2.0f64.ln_gamma().0, 0.0f64);
assert_eq!(2.0f64.ln_gamma().1, 1);
assert_approx_eq!(3.0f64.ln_gamma().0, 2.0f64.ln());
assert_eq!(3.0f64.ln_gamma().1, 1);
assert_approx_eq!((-0.5f64).ln_gamma().0, (2.0 * consts::PI.sqrt()).ln());
assert_eq!((-0.5f64).ln_gamma().1, -1);
}

#[test]
fn test_real_consts() {
use super::consts;
Expand Down
2 changes: 2 additions & 0 deletions library/std/src/sys/unix/cmath.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,6 @@ extern "C" {
pub fn tanhf(n: f32) -> f32;
pub fn tgamma(n: f64) -> f64;
pub fn tgammaf(n: f32) -> f32;
pub fn lgamma_r(n: f64, s: &mut i32) -> f64;
pub fn lgammaf_r(n: f32, s: &mut i32) -> f32;
}
4 changes: 3 additions & 1 deletion library/std/src/sys/windows/cmath.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#![cfg(not(test))]

use libc::{c_double, c_float};
use libc::{c_double, c_float, c_int};

extern "C" {
pub fn acos(n: c_double) -> c_double;
Expand All @@ -25,6 +25,8 @@ extern "C" {
pub fn tanh(n: c_double) -> c_double;
pub fn tgamma(n: c_double) -> c_double;
pub fn tgammaf(n: c_float) -> c_float;
pub fn lgamma_r(n: c_double, s: &mut c_int) -> c_double;
pub fn lgammaf_r(n: c_float, s: &mut c_int) -> c_float;
}

pub use self::shims::*;
Expand Down

0 comments on commit 5a57f24

Please sign in to comment.