From 68839c3dda175f376d1f2c46dd7480523a1b30ad Mon Sep 17 00:00:00 2001 From: Stefan Plantikow Date: Sun, 20 Nov 2011 18:44:37 +0100 Subject: [PATCH] Added logarithm functions for floats to std::math Thanks to marijn for helping with #[link_name] --- src/lib/math.rs | 42 ++++++++++++++++++++++++++++++++++++++++ src/test/stdtest/math.rs | 39 +++++++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+) diff --git a/src/lib/math.rs b/src/lib/math.rs index 47cfdef323ed..3f4625aae130 100644 --- a/src/lib/math.rs +++ b/src/lib/math.rs @@ -10,6 +10,11 @@ native mod libc { fn acos(n: float) -> float; fn tan(n: float) -> float; fn atan(n: float) -> float; + #[link_name="log"] + fn ln(n: float) -> float; + fn log2(n: float) -> float; + fn log10(n: float) -> float; + fn log1p(n: float) -> float; } /* @@ -81,3 +86,40 @@ Function: max Returns the maximum of two values */ fn max(x: T, y: T) -> T { x < y ? y : x } + +/* +Const: e + +Euler's number +*/ +const e: float = 2.718281828459045235; + +/* +Function: ln + +Returns the natural logaritm +*/ +fn ln(n: float) -> float { libc::ln(n) } + +/* +Function: log2 + +Returns the logarithm to base 2 +*/ +fn log2(n: float) -> float { libc::log2(n) } + +/* +Function: log2 + +Returns the logarithm to base 10 +*/ +fn log10(n: float) -> float { libc::log10(n) } + + +/* +Function: log1p + +Returns the natural logarithm of `1+n` accurately, +even for very small values of `n` +*/ +fn ln1p(n: float) -> float { libc::log1p(n) } diff --git a/src/test/stdtest/math.rs b/src/test/stdtest/math.rs index 413f3377653b..b09302000a67 100644 --- a/src/test/stdtest/math.rs +++ b/src/test/stdtest/math.rs @@ -1,5 +1,6 @@ use std; import std::math::*; +import std::float; #[test] fn test_sqrt() { @@ -32,3 +33,41 @@ fn test_angle() { assert angle((1f, 1f)) == 0.25 * pi; assert angle((0f, 1f)) == 0.5 * pi; } + + +#[test] +fn test_log_functions() { + assert ln(1.0) == 0.0; + assert log2(1.0) == 0.0; + assert log10(1.0) == 0.0; + + assert ln(e) == 1.0; + assert log2(2.0) == 1.0; + assert log10(10.0) == 1.0; + + assert ln(e*e*e*e) == 4.0; + assert log2(256.0) == 8.0; + assert log10(1000.0) == 3.0; + + assert ln(0.0) == float::neg_infinity; + assert log2(0.0) == float::neg_infinity; + assert log10(0.0) == float::neg_infinity; + + assert ln(-0.0) == float::neg_infinity; + assert log2(-0.0) == float::neg_infinity; + assert log10(-0.0) == float::neg_infinity; + + assert float::isNaN(ln(-1.0)); + assert float::isNaN(log2(-1.0)); + assert float::isNaN(log10(-1.0)); + + assert ln(float::infinity) == float::infinity; + assert log2(float::infinity) == float::infinity; + assert log10(float::infinity) == float::infinity; + + assert ln1p(0.0) == 0.0; + assert ln1p(-0.0) == 0.0; + assert ln1p(-1.0) == float::neg_infinity; + assert float::isNaN(ln1p(-2.0f)); + assert ln1p(float::infinity) == float::infinity; +} \ No newline at end of file