Imports name this capability’s declared dependencies, which fune builds next to it in your project; each one links to its page.
use super::funejson::Value; ← the fune runtime: the JSON value the test vectors use; fune build keeps it only where a signature takes one
// fdlibm's split of ln 2: the high part has trailing zero bits, so e * LN2_HI
// is exact for any exponent a double can have.
const LN2_HI: f64 = 6.93147180369123816490e-01;
const LN2_LO: f64 = 1.90821492927058770002e-10;
const SQRT2: f64 = 1.4142135623730951;
/// Natural logarithm using only +, -, * and /.
///
/// `f64::ln` calls the platform's maths library, whose last bit may differ
/// from JavaScript's and Python's. This follows the same steps in the same
/// order as the other two, so all three return the same double.
///
/// # Panics
/// Panics unless `x` is finite and greater than zero.
pub fn ln(x: f64) -> f64 {
if !x.is_finite() || x <= 0.0 {
panic!("ln is only defined for finite numbers greater than zero, received {}", x);
}
let mut m = x;
let mut e = 0i64;
while m >= 2.0 {
m /= 2.0;
e += 1;
}
while m < 1.0 {
m *= 2.0;
e -= 1;
}
if m > SQRT2 {
m /= 2.0;
e += 1;
}
let f = m - 1.0;
let s = f / (2.0 + f);
let z = s * s;
let mut p = 1.0 / 25.0;
p = 1.0 / 23.0 + z * p;
p = 1.0 / 21.0 + z * p;
p = 1.0 / 19.0 + z * p;
p = 1.0 / 17.0 + z * p;
p = 1.0 / 15.0 + z * p;
p = 1.0 / 13.0 + z * p;
p = 1.0 / 11.0 + z * p;
p = 1.0 / 9.0 + z * p;
p = 1.0 / 7.0 + z * p;
p = 1.0 / 5.0 + z * p;
p = 1.0 / 3.0 + z * p;
let lnm = 2.0 * s + 2.0 * s * (z * p);
let ef = e as f64;
ef * LN2_HI + (ef * LN2_LO + lnm)
}
pub fn fune_vector(args: &[Value]) -> Value {
Value::Float(ln(args[0].as_f64()))
}