diff --git a/Cargo.toml b/Cargo.toml index 12698b7af..c20fede22 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,11 +22,8 @@ checked = [] [workspace] members = [ "crates/compiler-builtins-smoke-test", - "crates/libm-test", - "crates/test-framework" + "crates/libm-test" ] [dev-dependencies] no-panic = "0.1.8" -libm-test = { version = "0.*", path = "./crates/libm-test" } -rand = "0.6.5" \ No newline at end of file diff --git a/ci/run.sh b/ci/run.sh index 6e4a8d27d..542206b2c 100755 --- a/ci/run.sh +++ b/ci/run.sh @@ -4,7 +4,7 @@ set -ex TARGET=$1 cargo test --target $TARGET -cargo test --features 'checked libm-test/conformance' --target $TARGET - cargo test --target $TARGET --release -cargo test --features 'checked libm-test/conformance' --target $TARGET --release + +cargo test -p libm-test --target $TARGET +cargo test -p libm-test --target $TARGET --release diff --git a/crates/libm-test/Cargo.toml b/crates/libm-test/Cargo.toml index 3bdd9335b..b2f37858a 100644 --- a/crates/libm-test/Cargo.toml +++ b/crates/libm-test/Cargo.toml @@ -3,15 +3,7 @@ name = "libm-test" version = "0.1.0" authors = ["Benjamin Schultzer "] -[lib] -proc-macro = true -test = false - [dependencies] -test-framework = { version = "0.*", path = "./../test-framework" } -proc-macro2 = { version = "0.4", features = ["nightly"] } -quote = "0.6" -syn = { version = "0.15", features = ["full"] } - -[features] -conformance = [] \ No newline at end of file +libm = { version = "0.*", path = "../../" } +paste = "0.1.5" +rand = "0.6.5" \ No newline at end of file diff --git a/crates/libm-test/build.rs b/crates/libm-test/build.rs new file mode 100644 index 000000000..45a868441 --- /dev/null +++ b/crates/libm-test/build.rs @@ -0,0 +1,13 @@ +use std::env; + +fn main() { + println!("cargo:rerun-if-changed=build.rs"); + let opt_level = env::var("OPT_LEVEL") + .ok() + .and_then(|s| s.parse().ok()) + .unwrap_or(0); + let profile = env::var("PROFILE").unwrap_or(String::new()); + if profile == "release" || opt_level >= 2 { + println!("cargo:rustc-cfg=optimized"); + } +} diff --git a/crates/libm-test/src/conformance.rs b/crates/libm-test/src/conformance.rs new file mode 100644 index 000000000..b4e0f5481 --- /dev/null +++ b/crates/libm-test/src/conformance.rs @@ -0,0 +1,461 @@ +#[cfg(test)] +use core::{f32, f64}; +#[cfg(test)] +use rand::Rng; + +macro_rules! forward { + ($func:ident, $x:ident) => ( + paste::item! { + #[cfg(test)] + extern "C" { pub fn [<$func>](x: $x) -> $x; } + + #[test] + pub fn [<$func _matches>]() { + let mut r = rand::thread_rng(); + for x in [$x::NAN, -$x::NAN, $x::INFINITY, $x::NEG_INFINITY].iter() { + let expected = unsafe { $func(*x) }; + let result = libm::$func(*x); + if !crate::[](expected, result) { + panic!("INPUT: {:?} EXPECTED: {:?} ACTUAL {:?}", x, expected, result); + } + } + for _ in 0..500 { + let x = r.gen::<$x>(); + let expected = unsafe { $func(x) }; + let result = libm::$func(x); + if !crate::[](expected, result) { + panic!("INPUT: {:?} EXPECTED: {:?} ACTUAL {:?}", x, expected, result); + } + } + } + } + ); + ($func:ident, $x:ty, $y:ty) => ( + paste::item! { + #[cfg(test)] + extern "C" { pub fn [<$func>](x: $x, y: $y) -> $x; } + + #[test] + pub fn [<$func _matches>]() { + let mut r = rand::thread_rng(); + for _ in 0..500 { + let x = r.gen::<$x>(); + let y = r.gen::<$y>(); + let expected = unsafe { $func(x, y) }; + let result = libm::$func(x, y); + if !crate::[](expected, result) { + panic!("INPUT: {:?} {:?} EXPECTED: {:?} ACTUAL {:?}", x, y, expected, result); + } + } + } + } +); + ($func:ident, $x:ty, $y:ty, $z:ty) => ( + paste::item! { + #[cfg(test)] + extern "C" { pub fn [<$func>](x: $x, y: $y, z: $z) -> $x; } + + #[test] + pub fn [<$func _matches>]() { + let mut r = rand::thread_rng(); + for _ in 0..500 { + let x = r.gen::<$x>(); + let y = r.gen::<$y>(); + let z = r.gen::<$z>(); + let expected = unsafe { $func(x, y, z) }; + let result = libm::$func(x, y, z); + if !crate::[](expected, result) { + panic!("INPUT: {:?} {:?} {:?} EXPECTED: {:?} ACTUAL {:?}", x, y, z, expected, result); + } + } + } + } + ); +} +macro_rules! bessel { + ($($func:ident);*) => ($( + paste::item! { + #[cfg(test)] + extern "C" { pub fn [<$func>](n: i32, x: f64) -> f64; } + + #[test] + pub fn [<$func _matches>]() { + let mut r = rand::thread_rng(); + for _ in 0..500 { + let mut n = r.gen::(); + n &= 0xffff; + let x = r.gen::(); + let expected = unsafe { [<$func>](n, x) }; + let result = libm::[<$func>](n, x); + if !crate::equalf64(expected, result) { + panic!("INPUT: {:?} {:?} EXPECTED: {:?} ACTUAL {:?}", n, x, expected, result); + } + } + } + + #[cfg(test)] + extern "C" { pub fn [<$func f>](n: i32, x: f32) -> f32; } + + #[test] + pub fn [<$func f _matches>]() { + let mut r = rand::thread_rng(); + for _ in 0..500 { + let mut n = r.gen::(); + n &= 0xffff; + let x = r.gen::(); + let expected = unsafe { [<$func f>](n, x) }; + let result = libm::[<$func f>](n, x); + if !crate::equalf32(expected, result) { + panic!("INPUT: {:?} {:?} EXPECTED: {:?} ACTUAL {:?}", n, x, expected, result); + } + } + } + } +)*); +($($func:ident),*) => ($( + paste::item! { + #[cfg(test)] + extern "C" { pub fn [<$func>](x: f64) -> f64; } + + #[test] + pub fn [<$func _matches>]() { + let mut r = rand::thread_rng(); + for _ in 0..500 { + let x = r.gen::(); + let expected = unsafe { [<$func>](x) }; + let result = libm::[<$func>](x); + if !crate::equalf64(expected, result) { + panic!("INPUT: {:?} EXPECTED: {:?} ACTUAL {:?}", x, expected, result); + } + } + } + + #[cfg(test)] + extern "C" { pub fn [<$func f>](x: f32) -> f32; } + + #[test] + pub fn [<$func f _matches>]() { + let mut r = rand::thread_rng(); + for _ in 0..500 { + let x = r.gen::(); + let expected = unsafe { [<$func f>](x) }; + let result = libm::[<$func f>](x); + if !crate::equalf32(expected, result) { + panic!("INPUT: {:?} EXPECTED: {:?} ACTUAL {:?}", x, expected, result); + } + } + } + } +)*); +} + +macro_rules! unary { + ($($func:ident),*) => ($( + paste::item! { + forward!($func, f64); + forward!([<$func f>], f32); + } + )*); +} + +macro_rules! binary { + ($($func:ident),*) => ($( + paste::item! { + forward!($func, f64, f64); + forward!([<$func f>], f32, f32); + } + )*); +} + +macro_rules! trinary {($($func:ident),*) => {$( + paste::item! { + forward!($func, f64, f64, f64); + forward!([<$func f>], f32, f32, f32); + } +)*}} + +unary!( + acos, acosh, asin, atan, cbrt, ceil, cos, cosh, erf, exp, exp2, exp10, expm1, fabs, floor, + lgamma, log, log1p, log2, log10, round, sin, sinh, sqrt, tan, tanh, tgamma, trunc +); +binary!(atan2, copysign, fdim, fmax, fmin, fmod, hypot, pow); // remainder +trinary!(fma); +bessel!(jn; yn); +bessel!(j0, y0, j1, y1); + +// special cases +paste::item! { + #[cfg(test)] + extern "C" { pub fn scalbn(x: f64, n: i32) -> f64; } + + #[test] + pub fn scalbn_matches() { + let mut r = rand::thread_rng(); + for _ in 0..500 { + let n = r.gen::(); + let x = r.gen::(); + let expected = unsafe { scalbn(x, n) }; + let result = libm::scalbn(x, n); + if !crate::equalf64(expected, result) { + panic!("INPUT: {:?} {:?} EXPECTED: {:?} ACTUAL {:?}", x, n, expected, result); + } + } + } + + #[cfg(test)] + extern "C" { pub fn scalbnf(x: f32, n: i32) -> f32; } + + #[test] + pub fn scalbnf_matches() { + let mut r = rand::thread_rng(); + for _ in 0..500 { + let n = r.gen::(); + let x = r.gen::(); + let expected = unsafe { scalbnf(x, n) }; + let result = libm::scalbnf(x, n); + if !crate::equalf32(expected, result) { + panic!("INPUT: {:?} {:?} EXPECTED: {:?} ACTUAL {:?}", x, n, expected, result); + } + } + } + + #[cfg(test)] + extern "C" { pub fn ilogb(x: f64) -> i32; } + + #[test] + pub fn ilogb_matches() { + for x in [f64::NAN, -f64::NAN, f64::INFINITY, f64::NEG_INFINITY].iter() { + let expected = unsafe { ilogb(*x) }; + let result = libm::ilogb(*x); + if !crate::equali32(expected, result) { + panic!("INPUT: {:?} EXPECTED: {:?} ACTUAL {:?}", x, expected, result); + } + } + + let mut r = rand::thread_rng(); + for _ in 0..500 { + let x = r.gen::(); + let expected = unsafe { ilogb(x) }; + let result = libm::ilogb(x); + if !crate::equali32(expected, result) { + panic!("INPUT: {:?} EXPECTED: {:?} ACTUAL {:?}", x, expected, result); + } + } + } + + #[cfg(test)] + extern "C" { pub fn ilogbf(x: f32) -> i32; } + + #[test] + pub fn ilogbf_matches() { + for x in [f32::NAN, -f32::NAN, f32::INFINITY, f32::NEG_INFINITY].iter() { + let expected = unsafe { ilogbf(*x) }; + let result = libm::ilogbf(*x); + if !crate::equali32(expected, result) { + panic!("INPUT: {:?} EXPECTED: {:?} ACTUAL {:?}", x, expected, result); + } + } + + let mut r = rand::thread_rng(); + for _ in 0..500 { + let x = r.gen::(); + let expected = unsafe { ilogbf(x) }; + let result = libm::ilogbf(x); + if !crate::equali32(expected, result) { + panic!("INPUT: {:?} EXPECTED: {:?} ACTUAL {:?}", x, expected, result); + } + } + } + + #[cfg(test)] + extern "C" { pub fn modf(x: f64, y: *mut f64) -> f64; } + + #[test] + pub fn modf_matches() { + for x in [f64::NAN, -f64::NAN, f64::INFINITY, f64::NEG_INFINITY].iter() { + let mut b = 0.; + let a = unsafe { modf(*x, &mut b)}; + let (c, d) = libm::modf(*x); + if !crate::equalf64(a, c) || !crate::equalf64(b, d) { + panic!("INPUT: {:?} EXPECTED: {:?} ACTUAL {:?}", x, (a, b), (c, d)); + } + } + let mut r = rand::thread_rng(); + for _ in 0..500 { + let mut b = 0.; + let x = r.gen::(); + let a = unsafe { modf(x, &mut b)}; + let (c, d) = libm::modf(x); + if !crate::equalf64(a, c) || !crate::equalf64(b, d) { + panic!("INPUT: {:?} EXPECTED: {:?} ACTUAL {:?}", x, (a, b), (c, d)); + } + } + } + + #[cfg(test)] + extern "C" { pub fn modff(x: f32, y: *mut f32) -> f32; } + + #[test] + pub fn modff_matches() { + for x in [f32::NAN, -f32::NAN, f32::INFINITY, f32::NEG_INFINITY].iter() { + let mut b = 0.; + let a = unsafe { modff(*x, &mut b) }; + let (c, d) = libm::modff(*x); + if !crate::equalf32(a, c) || !crate::equalf32(b, d) { + panic!("INPUT: {:?} EXPECTED: {:?} ACTUAL {:?}", x, (a, b), (c, d)); + } + } + let mut r = rand::thread_rng(); + for _ in 0..500 { + let mut b = 0.; + let x = r.gen::(); + let a = unsafe { modff(x, &mut b) }; + let (c, d) = libm::modff(x); + if !crate::equalf32(a, c) || !crate::equalf32(b, d) { + panic!("INPUT: {:?} EXPECTED: {:?} ACTUAL {:?}", x, (a, b), (c, d)); + } + } + } + + #[cfg(test)] + extern "C" { pub fn remquo(x: f64, y: f64, b: *mut i32) -> f64; } + + #[test] + pub fn remquo_matches() { + let mut r = rand::thread_rng(); + for _ in 0..500 { + let mut b = 0; + let x = r.gen::(); + let y = r.gen::(); + let a = unsafe { remquo(x, y, &mut b)}; + let (c, d) = libm::remquo(x, y); + if !crate::equalf64(a, c) || !crate::equali32(b, d) { + panic!("INPUT: {:?} EXPECTED: {:?} ACTUAL {:?}", x, (a, b), (c, d)); + } + } + } + + #[cfg(test)] + extern "C" { pub fn remquof(x: f32, y: f32, b: *mut i32) -> f32; } + + #[test] + pub fn remquof_matches() { + let mut r = rand::thread_rng(); + for _ in 0..500 { + let mut b = 0; + let x = r.gen::(); + let y = r.gen::(); + let a = unsafe { remquof(x, y, &mut b)}; + let (c, d) = libm::remquof(x, y); + if !crate::equalf32(a, c) || !crate::equali32(b, d) { + panic!("INPUT: {:?} EXPECTED: {:?} ACTUAL {:?}", x, (a, b), (c, d)); + } + } + } + + #[cfg(test)] + extern "C" { pub fn frexp(x: f64, y: *mut i32) -> f64; } + + #[test] + pub fn frexp_matches() { + let mut r = rand::thread_rng(); + for x in [f64::NAN, -f64::NAN, f64::INFINITY, f64::NEG_INFINITY].iter() { + let mut b = r.gen::(); + let a = unsafe { frexp(*x, &mut b) }; + let (c, d) = libm::frexp(*x); + if !crate::equalf64(a, c) || !crate::equali32(b, d) { + panic!("INPUT: {:?} EXPECTED: {:?} ACTUAL {:?}", x, (a, b), (c, d)); + } + } + for _ in 0..500 { + let x = r.gen::(); + let mut b = r.gen::(); + let a = unsafe { frexp(x, &mut b) }; + let (c, d) = libm::frexp(x); + if !crate::equalf64(a, c) || !crate::equali32(b, d) { + panic!("INPUT: {:?} EXPECTED: {:?} ACTUAL {:?}", x, (a, b), (c, d)); + } + } + } + + #[cfg(test)] + extern "C" { pub fn frexpf(x: f32, y: *mut i32) -> f32; } + + #[test] + pub fn frexpf_matches() { + let mut r = rand::thread_rng(); + for x in [f32::NAN, -f32::NAN, f32::INFINITY, f32::NEG_INFINITY].iter() { + let mut b = 0; + let a = unsafe { frexpf(*x, &mut b) }; + let (c, d) = libm::frexpf(*x); + if !crate::equalf32(a, c) || !crate::equali32(b, d) { + panic!("INPUT: {:?} EXPECTED: {:?} ACTUAL {:?}", x, (a, b), (c, d)); + } + } + for _ in 0..500 { + let x = r.gen::(); + let mut b = 0; + let a = unsafe { frexpf(x, &mut b) }; + let (c, d) = libm::frexpf(x); + if !crate::equalf32(a, c) || !crate::equali32(b, d) { + panic!("INPUT: {:?} EXPECTED: {:?} ACTUAL {:?}", x, (a, b), (c, d)); + } + } + } + + #[cfg(test)] + extern "C" { pub fn sincos(x: f64, sin: *mut f64, cos: *mut f64); } + + #[test] + pub fn sincos_matches() { + for x in [f64::NAN, -f64::NAN, f64::INFINITY, f64::NEG_INFINITY].iter() { + let mut sin = 0.; + let mut cos = 0.; + unsafe { sincos(*x, &mut sin, &mut cos) }; + let result = libm::sincos(*x); + if !crate::equalf64(sin, result.0) || !crate::equalf64(cos, result.1) { + panic!("INPUT: {:?} EXPECTED: {:?} ACTUAL {:?}", x, (sin, cos), result); + } + } + + let mut r = rand::thread_rng(); + for _ in 0..500 { + let x = r.gen::(); + let mut sin = 0.; + let mut cos = 0.; + unsafe { sincos(x, &mut sin, &mut cos) }; + let result = libm::sincos(x); + if !crate::equalf64(sin, result.0) || !crate::equalf64(cos, result.1) { + panic!("INPUT: {:?} EXPECTED: {:?} ACTUAL {:?}", x, (sin, cos), result); + } + } + } + + #[cfg(test)] + extern "C" { pub fn sincosf(x: f32, sin: *mut f32, cos: *mut f32); } + + #[test] + pub fn sincosf_matches() { + for x in [f32::NAN, -f32::NAN, f32::INFINITY, f32::NEG_INFINITY].iter() { + let mut sin = 0.; + let mut cos = 0.; + unsafe { sincosf(*x, &mut sin, &mut cos) }; + let result = libm::sincosf(*x); + if !crate::equalf32(sin, result.0) || !crate::equalf32(cos, result.1) { + panic!("INPUT: {:?} EXPECTED: {:?} ACTUAL {:?}", x, (sin, cos), result); + } + } + + let mut r = rand::thread_rng(); + for _ in 0..500 { + let x = r.gen::(); + let mut sin = 0.; + let mut cos = 0.; + unsafe { sincosf(x, &mut sin, &mut cos) }; + let result = libm::sincosf(x); + if !crate::equalf32(sin, result.0) || !crate::equalf32(cos, result.1) { + panic!("INPUT: {:?} EXPECTED: {:?} ACTUAL {:?}", x, (sin, cos), result); + } + } + } +} diff --git a/crates/libm-test/src/lib.rs b/crates/libm-test/src/lib.rs index 6d32201c5..33e6bd9df 100644 --- a/crates/libm-test/src/lib.rs +++ b/crates/libm-test/src/lib.rs @@ -1,31 +1,66 @@ -extern crate proc_macro; -extern crate proc_macro2; -extern crate syn; -extern crate test_framework; -#[macro_use] -extern crate quote; -use proc_macro::TokenStream; +#![cfg(test)] +extern crate core; +extern crate libm; +extern crate paste; +extern crate rand; -#[proc_macro_attribute] -pub fn libm_test(_attr: TokenStream, item: TokenStream) -> TokenStream { - let item = match syn::parse::(item) { - Ok(s) => s, - Err(e) => return e.to_compile_error().into(), - }; - let func = match item { - syn::Item::Fn(ref f) => f, - _ => panic!("must be attached to a function"), - }; - let name = &func.ident; - let mut tests = proc_macro2::TokenStream::new(); - if cfg!(feature = "conformance") { - tests.extend(test_framework::conformance::test(&name, 1)) // ULP hardcoded to 1. - } - let tests: proc_macro2::TokenStream = - tests.to_string().parse().expect("cannot parse tokenstream"); - let tts: proc_macro2::TokenStream = quote! { - #item - #tests - }; - tts.into() +pub mod conformance; + +#[cfg(target_arch = "x86_64")] +pub mod validation; + +#[cfg(test)] +pub fn equalf64(x: f64, y: f64) -> bool { + if x.is_nan() != y.is_nan() { + // one is nan but the other is not + return false; + } + if x.is_nan() && y.is_nan() { + return true; + } + if x.is_infinite() != y.is_infinite() { + // one is inf but the other is not + return false; + } + if x.is_infinite() != y.is_infinite() { + // one is inf but the other is not + return false; + } + let xi: i64 = unsafe { core::intrinsics::transmute(x) }; + let yi: i64 = unsafe { core::intrinsics::transmute(y) }; + if (xi < 0) != (yi < 0) { + // different sign + return false; + } + let ulps = (xi - yi).abs(); + ulps <= 1 +} + +#[cfg(test)] +pub fn equalf32(x: f32, y: f32) -> bool { + if x.is_nan() != y.is_nan() { + // one is nan but the other is not + return false; + } + if x.is_nan() && y.is_nan() { + return true; + } + if x.is_infinite() != y.is_infinite() { + // one is inf but the other is not + return false; + } + let xi: i32 = unsafe { core::intrinsics::transmute(x) }; + let yi: i32 = unsafe { core::intrinsics::transmute(y) }; + if (xi < 0) != (yi < 0) { + // different sign + return false; + } + let ulps = (xi - yi).abs(); + ulps <= 1 +} + +#[cfg(test)] +pub fn equali32(x: i32, y: i32) -> bool { + let ulps = (x - y).abs(); + ulps <= 1 } diff --git a/crates/libm-test/src/validation.rs b/crates/libm-test/src/validation.rs new file mode 100644 index 000000000..fef958ab8 --- /dev/null +++ b/crates/libm-test/src/validation.rs @@ -0,0 +1,118 @@ +macro_rules! unary { + ($($func:ident),*) => ($( + paste::item! { + #[cfg(test)] + extern "C" { pub fn [<$func f>](x: f32) -> f32; } + + #[test] + pub fn [<$func f _validation>]() { + if !cfg!(optmaized) { return } + for i in 0..u32::max_value() { + let x = f32::from_bits(i); + let expected = unsafe { [<$func f>](x) }; + let result = libm::[<$func f>](x); + if !crate::equalf32(expected, result) { + panic!("INPUT: {:?} EXPECTED: {:?} ACTUAL {:?}", x, expected, result); + } + } + } + } + )*); +} + +unary!( + acos, acosh, asin, atan, cbrt, ceil, cos, cosh, erf, exp, exp2, exp10, expm1, fabs, floor, j0, + j1, lgamma, log, log1p, log2, log10, round, sin, sinh, sqrt, tan, tanh, tgamma, trunc, y0, y1 +); + +#[cfg(test)] +extern "C" { + pub fn ilogbf(x: f32) -> i32; +} + +#[test] +pub fn ilogbf_validation() { + if !cfg!(optmaized) { + return; + } + for i in 0..u32::max_value() { + let x = f32::from_bits(i); + let expected = unsafe { ilogbf(x) }; + let result = libm::ilogbf(x); + if !crate::equali32(expected, result) { + panic!( + "INPUT: {:?} EXPECTED: {:?} ACTUAL {:?}", + x, expected, result + ); + } + } +} + +#[cfg(test)] +extern "C" { + pub fn modff(x: f32, y: *mut f32) -> f32; +} + +#[test] +pub fn modff_validation() { + if !cfg!(optmaized) { + return; + } + for i in 0..u32::max_value() { + let mut b = 0.; + let x = f32::from_bits(i); + let a = unsafe { modff(x, &mut b) }; + let (c, d) = libm::modff(x); + if !crate::equalf32(a, c) || !crate::equalf32(b, d) { + panic!("INPUT: {:?} EXPECTED: {:?} ACTUAL {:?}", x, (a, b), (c, d)); + } + } +} + +#[cfg(test)] +extern "C" { + pub fn frexpf(x: f32, y: *mut i32) -> f32; +} + +#[test] +pub fn frexpf_validation() { + if !cfg!(optmaized) { + return; + } + for i in 0..u32::max_value() { + let mut b = 0; + let x = f32::from_bits(i); + let a = unsafe { frexpf(x, &mut b) }; + let (c, d) = libm::frexpf(x); + if !crate::equalf32(a, c) || !crate::equali32(b, d) { + panic!("INPUT: {:?} EXPECTED: {:?} ACTUAL {:?}", x, (a, b), (c, d)); + } + } +} + +#[cfg(test)] +extern "C" { + pub fn sincosf(x: f32, sin: *mut f32, cos: *mut f32); +} + +#[test] +pub fn sincosf_validation() { + if !cfg!(optmaized) { + return; + } + for i in 0..u32::max_value() { + let x = f32::from_bits(i); + let mut sin = 0.; + let mut cos = 0.; + unsafe { sincosf(x, &mut sin, &mut cos) }; + let result = libm::sincosf(x); + if !crate::equalf32(sin, result.0) || !crate::equalf32(cos, result.1) { + panic!( + "INPUT: {:?} EXPECTED: {:?} ACTUAL {:?}", + x, + (sin, cos), + result + ); + } + } +} diff --git a/crates/test-framework/Cargo.toml b/crates/test-framework/Cargo.toml deleted file mode 100644 index 35fb03301..000000000 --- a/crates/test-framework/Cargo.toml +++ /dev/null @@ -1,14 +0,0 @@ -[package] -name = "test-framework" -version = "0.1.0" -authors = ["Benjamin Schultzer "] - -[lib] -test = false - -[dependencies] -proc-macro2 = { version = "0.4", features = ["nightly"] } -paste = "0.1.5" -quote = "0.6" -syn = { version = "0.15", features = ["full"] } -rand = "0.6.5" \ No newline at end of file diff --git a/crates/test-framework/src/conformance.rs b/crates/test-framework/src/conformance.rs deleted file mode 100644 index 6df0802e5..000000000 --- a/crates/test-framework/src/conformance.rs +++ /dev/null @@ -1,699 +0,0 @@ -use proc_macro2::{Ident, TokenStream}; - -fn equalf64() -> TokenStream { - quote! { - fn equal(x: f64, y: f64, max_ulp_diff: usize) -> bool { - if x.is_nan() != y.is_nan() { // one is nan but the other is not - return false; - } - if x.is_nan() && y.is_nan() { - return true; - } - if x.is_infinite() != y.is_infinite() { // one is inf but the other is not - return false; - } - if x.is_infinite() != y.is_infinite() { // one is inf but the other is not - return false; - } - let xi: i64 = unsafe { core::intrinsics::transmute(x) }; - let yi: i64 = unsafe { core::intrinsics::transmute(y) }; - if (xi < 0) != (yi < 0) { // different sign - return false; - } - let ulps = (xi - yi).abs() as usize; - ulps <= max_ulp_diff - } - } -} - -fn equalf32() -> TokenStream { - quote! { - fn equal(x: f32, y: f32, max_ulp_diff: usize) -> bool { - if x.is_nan() != y.is_nan() { // one is nan but the other is not - return false; - } - if x.is_nan() && y.is_nan() { - return true; - } - if x.is_infinite() != y.is_infinite() { // one is inf but the other is not - return false; - } - let xi: i32 = unsafe { core::intrinsics::transmute(x) }; - let yi: i32 = unsafe { core::intrinsics::transmute(y) }; - if (xi < 0) != (yi < 0) { // different sign - return false; - } - let ulps = (xi - yi).abs() as usize; - ulps <= max_ulp_diff - } - } -} - -fn equali32() -> TokenStream { - quote! { - fn equal(x: i32, y: i32, max_ulp_diff: usize) -> bool { - let ulps = (x - y).abs() as usize; - ulps <= max_ulp_diff - } - } -} - -macro_rules! forward { - ($func:ident, $x:ident) => ( - pub fn $func(ulp: usize) -> TokenStream { - let equal: TokenStream = paste::expr!{ []() }; - quote! { - #[cfg(test)] - mod conformance { - use rand::Rng; - use core::$x::{NAN, INFINITY, NEG_INFINITY}; - extern "C" { pub fn $func(x: $x) -> $x; } - #equal - #[test] - pub fn test() { - let mut r = rand::thread_rng(); - for x in [NAN, -NAN, INFINITY, NEG_INFINITY].iter() { - let expected = unsafe { $func(*x) }; - let result = super::$func(*x); - if !equal(expected, result, #ulp) { - panic!("INPUT: {:?} EXPECTED: {:?} ACTUAL {:?}", x, expected, result); - } - } - for _ in 0..500 { - let x = r.gen::<$x>(); - let expected = unsafe { $func(x) }; - let result = super::$func(x); - if !equal(expected, result, #ulp) { - panic!("INPUT: {:?} EXPECTED: {:?} ACTUAL {:?}", x, expected, result); - } - } - } - } - } - } - ); - ($func:ident, $x:ty, $y:ty) => ( - paste::item! { - pub fn $func(ulp: usize) -> TokenStream { - let equal: TokenStream = paste::expr!{ []() }; - quote! { - #[cfg(test)] - mod conformance { - use rand::Rng; - extern "C" { pub fn $func(x: $x, y: $y) -> $x; } - #equal - #[test] - pub fn test() { - let mut r = rand::thread_rng(); - for _ in 0..500 { - let x = r.gen::<$x>(); - let y = r.gen::<$y>(); - let expected = unsafe { $func(x, y) }; - let result = super::$func(x, y); - if !equal(expected, result, #ulp) { - panic!("INPUT: {:?} {:?} EXPECTED: {:?} ACTUAL {:?}", x, y, expected, result); - } - } - } - } - } - } - } -); - ($func:ident, $x:ty, $y:ty, $z:ty) => ( - paste::item! { - pub fn $func(ulp: usize) -> TokenStream { - let equal: TokenStream = paste::expr!{ []() }; - quote! { - #[cfg(test)] - mod conformance { - use rand::Rng; - use core::$x; - extern "C" { pub fn $func(x: $x, y: $y, z: $z) -> $x; } - #equal - #[test] - pub fn test() { - let mut r = rand::thread_rng(); - for _ in 0..500 { - let x = r.gen::<$x>(); - let y = r.gen::<$y>(); - let z = r.gen::<$z>(); - let expected = unsafe { $func(x, y, z) }; - let result = super::$func(x, y, z); - if !equal(expected, result, #ulp) { - panic!("INPUT: {:?} {:?} {:?} EXPECTED: {:?} ACTUAL {:?}", x, y, z, expected, result); - } - } - } - } - } - } - } - ); -} -macro_rules! bessel { - ($($func:ident);*) => ($( - paste::item! { - pub fn $func(ulp: usize) -> TokenStream { - let eq: TokenStream = equalf64(); - quote! { - #[cfg(test)] - mod [<$func>] { - mod conformance { - use rand::Rng; - extern "C" { pub fn [<$func>](n: i32, x: f64) -> f64; } - #eq - #[test] - pub fn test() { - let mut r = rand::thread_rng(); - for _ in 0..500 { - let mut n = r.gen::(); - n &= 0xffff; - let x = r.gen::(); - let expected = unsafe { $func(n, x) }; - let result = super::super::$func(n, x); - if !equal(expected, result, #ulp) { - panic!("INPUT: {:?} {:?} EXPECTED: {:?} ACTUAL {:?}", n, x, expected, result); - } - } - } - } - } - } - } - pub fn [<$func f>](ulp: usize) -> TokenStream { - let eq: TokenStream = equalf32(); - quote! { - #[cfg(test)] - mod [<$func f>] { - mod conformance { - use rand::Rng; - extern "C" { pub fn [<$func f>](n: i32, x: f32) -> f32; } - #eq - #[test] - pub fn test() { - let mut r = rand::thread_rng(); - for _ in 0..500 { - let mut n = r.gen::(); - n &= 0xffff; - let x = r.gen::(); - let expected = unsafe { [<$func f>](n, x) }; - let result = super::super::[<$func f>](n, x); - if !equal(expected, result, #ulp) { - panic!("INPUT: {:?} {:?} EXPECTED: {:?} ACTUAL {:?}", n, x, expected, result); - } - } - } - } - } - } - } - } -)*); -($($func:ident),*) => ($( - paste::item! { - pub fn $func(ulp: usize) -> TokenStream { - let eq: TokenStream = equalf64(); - quote! { - #[cfg(test)] - mod [<$func>] { - mod conformance { - use rand::Rng; - extern "C" { pub fn [<$func>](x: f64) -> f64; } - #eq - #[test] - pub fn test() { - let mut r = rand::thread_rng(); - for _ in 0..500 { - let x = r.gen::(); - let expected = unsafe { $func(x) }; - let result = super::super::$func(x); - if !equal(expected, result, #ulp) { - panic!("INPUT: {:?} EXPECTED: {:?} ACTUAL {:?}", x, expected, result); - } - } - } - } - } - } - } - pub fn [<$func f>](ulp: usize) -> TokenStream { - let eq: TokenStream = equalf32(); - quote! { - #[cfg(test)] - mod [<$func f>] { - mod conformance { - use rand::Rng; - extern "C" { pub fn [<$func f>](x: f32) -> f32; } - #eq - #[test] - pub fn test() { - let mut r = rand::thread_rng(); - for _ in 0..500 { - let x = r.gen::(); - let expected = unsafe { [<$func f>](x) }; - let result = super::super::[<$func f>](x); - if !equal(expected, result, #ulp) { - panic!("INPUT: {:?} EXPECTED: {:?} ACTUAL {:?}", x, expected, result); - } - } - } - } - } - } - } - } -)*); -} - -macro_rules! unary { - ($($func:ident),*) => ($( - paste::item! { - forward!($func, f64); - forward!([<$func f>], f32); - } - )*); -} - -macro_rules! binary { - ($($func:ident),*) => ($( - paste::item! { - forward!($func, f64, f64); - forward!([<$func f>], f32, f32); - } - )*); -} - -macro_rules! trinary {($($func:ident),*) => {$( - paste::item! { - forward!($func, f64, f64, f64); - forward!([<$func f>], f32, f32, f32); - } -)*}} - -macro_rules! generate { - ($($func:ident),*) => { - paste::item! { - pub fn test(name: &Ident, ulp: usize) -> TokenStream { - match format!("{}", name).as_ref() { - $( - stringify!([<$func f>]) => [<$func f>](ulp), - stringify!($func) => {$func(ulp)}, - )* - _ => quote! {}, - } - } - } - } -} -unary!( - acos, acosh, asin, atan, cbrt, ceil, cos, cosh, erf, exp, exp2, exp10, expm1, fabs, floor, - lgamma, log, log1p, log2, log10, round, sin, sinh, sqrt, tan, tanh, tgamma, trunc -); -binary!(atan2, copysign, fdim, fmax, fmin, fmod, hypot, pow, remainder); -trinary!(fma); -bessel!(jn; yn); -bessel!(j0, y0, j1, y1); - -/// special cases - -pub fn scalbn(ulp: usize) -> TokenStream { - let eq: TokenStream = equalf64(); - quote! { - #[cfg(test)] - mod conformance { - use rand::Rng; - use core::f64; - extern "C" { pub fn scalbn(x: f64, n: i32) -> f64; } - #eq - #[test] - pub fn test() { - let mut r = rand::thread_rng(); - for _ in 0..500 { - let n = r.gen::(); - let x = r.gen::(); - let expected = unsafe { scalbn(x, n) }; - let result = super::scalbn(x, n); - if !equal(expected, result, #ulp) { - panic!("INPUT: {:?} {:?} EXPECTED: {:?} ACTUAL {:?}", x, n, expected, result); - } - } - } - } - } -} -pub fn scalbnf(ulp: usize) -> TokenStream { - let eq: TokenStream = equalf32(); - quote! { - #[cfg(test)] - mod conformance { - use rand::Rng; - use core::f64; - extern "C" { pub fn scalbnf(x: f32, n: i32) -> f32; } - #eq - #[test] - pub fn test() { - let mut r = rand::thread_rng(); - for _ in 0..500 { - let n = r.gen::(); - let x = r.gen::(); - let expected = unsafe { scalbnf(x, n) }; - let result = super::scalbnf(x, n); - if !equal(expected, result, #ulp) { - panic!("INPUT: {:?} {:?} EXPECTED: {:?} ACTUAL {:?}", x, n, expected, result); - } - } - } - } - } -} - -pub fn ilogb(ulp: usize) -> TokenStream { - let eq: TokenStream = equali32(); - quote! { - #[cfg(test)] - mod conformance { - use rand::Rng; - use core::f64::{NAN, INFINITY, NEG_INFINITY}; - extern "C" { pub fn ilogb(x: f64) -> i32; } - #eq - #[test] - pub fn test() { - for x in [NAN, -NAN, INFINITY, NEG_INFINITY].iter() { - let expected = unsafe { ilogb(*x) }; - let result = super::ilogb(*x); - if !equal(expected, result, #ulp) { - panic!("INPUT: {:?} EXPECTED: {:?} ACTUAL {:?}", x, expected, result); - } - } - - let mut r = rand::thread_rng(); - for _ in 0..500 { - let x = r.gen::(); - let expected = unsafe { ilogb(x) }; - let result = super::ilogb(x); - if !equal(expected, result, #ulp) { - panic!("INPUT: {:?} EXPECTED: {:?} ACTUAL {:?}", x, expected, result); - } - } - } - } - } -} -pub fn ilogbf(ulp: usize) -> TokenStream { - let eq: TokenStream = equali32(); - quote! { - #[cfg(test)] - mod conformance { - use rand::Rng; - use core::f32::{NAN, INFINITY, NEG_INFINITY}; - extern "C" { pub fn ilogbf(x: f32) -> i32; } - #eq - #[test] - pub fn test() { - for x in [NAN, -NAN, INFINITY, NEG_INFINITY].iter() { - let expected = unsafe { ilogbf(*x) }; - let result = super::ilogbf(*x); - if !equal(expected, result, #ulp) { - panic!("INPUT: {:?} EXPECTED: {:?} ACTUAL {:?}", x, expected, result); - } - } - - let mut r = rand::thread_rng(); - for _ in 0..500 { - let x = r.gen::(); - let expected = unsafe { ilogbf(x) }; - let result = super::ilogbf(x); - if !equal(expected, result, #ulp) { - panic!("INPUT: {:?} EXPECTED: {:?} ACTUAL {:?}", x, expected, result); - } - } - } - } - } -} - -pub fn modf(ulp: usize) -> TokenStream { - let eq: TokenStream = equalf64(); - quote! { - #[cfg(test)] - mod conformance { - use rand::Rng; - use core::f64::{NAN, INFINITY, NEG_INFINITY}; - extern "C" { pub fn modf(x: f64, y: *mut f64) -> f64; } - #eq - #[test] - pub fn test() { - for x in [NAN, -NAN, INFINITY, NEG_INFINITY].iter() { - let mut b = 0.; - let a = unsafe { modf(*x, &mut b)}; - let (c, d) = super::modf(*x); - if !equal(a, c, #ulp) || !equal(b, d, #ulp) { - panic!("INPUT: {:?} EXPECTED: {:?} ACTUAL {:?}", x, (a, b), (c, d)); - } - } - let mut r = rand::thread_rng(); - for _ in 0..500 { - let mut b = 0.; - let x = r.gen::(); - let a = unsafe { modf(x, &mut b)}; - let (c, d) = super::modf(x); - if !equal(a, c, #ulp) || !equal(b, d, #ulp) { - panic!("INPUT: {:?} EXPECTED: {:?} ACTUAL {:?}", x, (a, b), (c, d)); - } - } - } - } - } -} - -pub fn modff(ulp: usize) -> TokenStream { - let eq: TokenStream = equalf32(); - quote! { - #[cfg(test)] - mod conformance { - use rand::Rng; - use core::f32::{NAN, INFINITY, NEG_INFINITY}; - extern "C" { pub fn modff(x: f32, y: *mut f32) -> f32; } - #eq - #[test] - pub fn test() { - for x in [NAN, -NAN, INFINITY, NEG_INFINITY].iter() { - let mut b = 0.; - let a = unsafe { modff(*x, &mut b) }; - let (c, d) = super::modff(*x); - if !equal(a, c, #ulp) || !equal(b, d, #ulp) { - panic!("INPUT: {:?} EXPECTED: {:?} ACTUAL {:?}", x, (a, b), (c, d)); - } - } - let mut r = rand::thread_rng(); - for _ in 0..500 { - let mut b = 0.; - let x = r.gen::(); - let a = unsafe { modff(x, &mut b) }; - let (c, d) = super::modff(x); - if !equal(a, c, #ulp) || !equal(b, d, #ulp) { - panic!("INPUT: {:?} EXPECTED: {:?} ACTUAL {:?}", x, (a, b), (c, d)); - } - } - } - } - } -} - -pub fn remquo(ulp: usize) -> TokenStream { - let eq: TokenStream = equalf64(); - quote! { - #[cfg(test)] - mod conformance { - use rand::Rng; - extern "C" { pub fn remquo(x: f64, y: f64, b: *mut i32) -> f64; } - #eq - #[test] - pub fn test() { - let mut r = rand::thread_rng(); - for _ in 0..500 { - let mut b = 0; - let x = r.gen::(); - let y = r.gen::(); - let a = unsafe { remquo(x, y, &mut b)}; - let (c, d) = super::remquo(x, y); - if !equal(a, c, #ulp) || !((b - d).abs() as usize <= #ulp) { - panic!("INPUT: {:?} EXPECTED: {:?} ACTUAL {:?}", x, (a, b), (c, d)); - } - } - } - } - } -} -pub fn remquof(ulp: usize) -> TokenStream { - let eq: TokenStream = equalf32(); - quote! { - #[cfg(test)] - mod conformance { - use rand::Rng; - extern "C" { pub fn remquof(x: f32, y: f32, b: *mut i32) -> f32; } - #eq - #[test] - pub fn test() { - let mut r = rand::thread_rng(); - for _ in 0..500 { - let mut b = 0; - let x = r.gen::(); - let y = r.gen::(); - let a = unsafe { remquof(x, y, &mut b)}; - let (c, d) = super::remquof(x, y); - if !equal(a, c, #ulp) || !((b - d).abs() as usize <= #ulp) { - panic!("INPUT: {:?} EXPECTED: {:?} ACTUAL {:?}", x, (a, b), (c, d)); - } - } - } - } - } -} -pub fn frexp(ulp: usize) -> TokenStream { - let eq: TokenStream = equalf64(); - quote! { - #[cfg(test)] - mod conformance { - use rand::Rng; - use core::f64::{NAN, INFINITY, NEG_INFINITY}; - extern "C" { pub fn frexp(x: f64, y: *mut i32) -> f64; } - #eq - #[test] - pub fn test() { - let mut r = rand::thread_rng(); - for x in [NAN, -NAN, INFINITY, NEG_INFINITY].iter() { - let mut b = r.gen::(); - let a = unsafe { frexp(*x, &mut b) }; - let (c, d) = super::frexp(*x); - if !equal(a, c, #ulp) || !((b - d).abs() as usize <= #ulp) { - panic!("INPUT: {:?} EXPECTED: {:?} ACTUAL {:?}", x, (a, b), (c, d)); - } - } - for _ in 0..500 { - let x = r.gen::(); - let mut b = r.gen::(); - let a = unsafe { frexp(x, &mut b) }; - let (c, d) = super::frexp(x); - if !equal(a, c, #ulp) || !((b - d).abs() as usize <= #ulp){ - panic!("INPUT: {:?} EXPECTED: {:?} ACTUAL {:?}", x, (a, b), (c, d)); - } - } - } - } - } -} -pub fn frexpf(ulp: usize) -> TokenStream { - let eq: TokenStream = equalf32(); - quote! { - #[cfg(test)] - mod conformance { - use rand::Rng; - use core::f32::{NAN, INFINITY, NEG_INFINITY}; - extern "C" { pub fn frexpf(x: f32, y: *mut i32) -> f32; } - #eq - #[test] - pub fn test() { - let mut r = rand::thread_rng(); - for x in [NAN, -NAN, INFINITY, NEG_INFINITY].iter() { - let mut b = r.gen::(); - let a = unsafe { frexpf(*x, &mut b) }; - let (c, d) = super::frexpf(*x); - if !equal(a, c, #ulp) || !((b - d).abs() as usize <= #ulp) { - panic!("INPUT: {:?} EXPECTED: {:?} ACTUAL {:?}", x, (a, b), (c, d)); - } - } - for _ in 0..500 { - let x = r.gen::(); - let mut b = r.gen::(); - let a = unsafe { frexpf(x, &mut b) }; - let (c, d) = super::frexpf(x); - if !equal(a, c, #ulp) || !((b - d).abs() as usize <= #ulp){ - panic!("INPUT: {:?} EXPECTED: {:?} ACTUAL {:?}", x, (a, b), (c, d)); - } - } - } - } - } -} - -pub fn sincos(ulp: usize) -> TokenStream { - let eq: TokenStream = equalf64(); - quote! { - #[cfg(test)] - mod conformance { - use rand::Rng; - use core::f64::{NAN, INFINITY, NEG_INFINITY}; - extern "C" { pub fn sincos(x: f64, sin: *mut f64, cos: *mut f64) -> () } - #eq - #[test] - pub fn test() { - for x in [NAN, -NAN, INFINITY, NEG_INFINITY].iter() { - let mut sin = 0.; - let mut cos = 0.; - unsafe { sincos(*x) }; - let result = super::sincos(*x); - if !equal(sin, result.0, #ulp) !equal(cos, result.1, #ulp) { - panic!("INPUT: {:?} EXPECTED: {:?} ACTUAL {:?}", x, expected, result); - } - } - - let mut r = rand::thread_rng(); - for _ in 0..500 { - let x = r.gen::(); - let mut sin = 0.; - let mut cos = 0.; - unsafe { sincos(x) }; - let result = super::sincos(x); - if !equal(sin, result.0, #ulp) !equal(cos, result.1, #ulp) { - panic!("INPUT: {:?} EXPECTED: {:?} ACTUAL {:?}", x, expected, result); - } - } - } - } - } -} -pub fn sincosf(ulp: usize) -> TokenStream { - let eq: TokenStream = equalf32(); - quote! { - #[cfg(test)] - mod conformance { - use rand::Rng; - use core::f32::{NAN, INFINITY, NEG_INFINITY}; - extern "C" { pub fn sincosf(x: f32, sin: *mut f32, cos: *mut f32) -> () } - #eq - #[test] - pub fn test() { - for x in [NAN, -NAN, INFINITY, NEG_INFINITY].iter() { - let mut sin = 0.; - let mut cos = 0.; - unsafe { sincos(*x) }; - let result = super::sincos(*x); - if !equal(sin, result.0, #ulp) !equal(cos, result.1, #ulp) { - panic!("INPUT: {:?} EXPECTED: {:?} ACTUAL {:?}", x, expected, result); - } - } - - let mut r = rand::thread_rng(); - for _ in 0..500 { - let x = r.gen::(); - let mut sin = 0.; - let mut cos = 0.; - unsafe { sincos(x) }; - let result = super::sincos(x); - if !equal(sin, result.0, #ulp) !equal(cos, result.1, #ulp) { - panic!("INPUT: {:?} EXPECTED: {:?} ACTUAL {:?}", x, expected, result); - } - } - } - } - } -} - -generate!( - acos, acosh, asin, atan, atan2, cbrt, ceil, copysign, cos, cosh, erf, exp, exp2, expm1, exp10, - fabs, fdim, floor, fma, fmod, frexp, hypot, ilogb, j0, y0, j1, y1, jn, yn, lgamma, log, log1p, - log2, log10, modf, pow, remainder, remquo, round, scalbn, sin, sinh, sqrt, tan, tanh, tgamma, - trunc -); diff --git a/crates/test-framework/src/lib.rs b/crates/test-framework/src/lib.rs deleted file mode 100644 index 5125b0429..000000000 --- a/crates/test-framework/src/lib.rs +++ /dev/null @@ -1,10 +0,0 @@ -#![recursion_limit = "256"] -extern crate paste; -extern crate proc_macro; -extern crate proc_macro2; -extern crate rand; -#[macro_use] -extern crate quote; -extern crate syn; - -pub mod conformance; diff --git a/src/lib.rs b/src/lib.rs index 499d087a9..824819dbf 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -16,12 +16,6 @@ feature(core_intrinsics) )] -#[cfg(test)] -extern crate libm_test; - -#[cfg(test)] -extern crate rand; - mod math; use core::{f32, f64}; diff --git a/src/math/acos.rs b/src/math/acos.rs index 3d7167b16..d5e1f6865 100644 --- a/src/math/acos.rs +++ b/src/math/acos.rs @@ -34,8 +34,6 @@ */ use super::sqrt; -#[cfg(test)] -use libm_test::libm_test; const PIO2_HI: f64 = 1.57079632679489655800e+00; /* 0x3FF921FB, 0x54442D18 */ const PIO2_LO: f64 = 6.12323399573676603587e-17; /* 0x3C91A626, 0x33145C07 */ @@ -64,7 +62,6 @@ fn r(z: f64) -> f64 { /// Returns values in radians, in the range of 0 to pi. #[inline] #[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)] -#[cfg_attr(test, libm_test)] pub fn acos(x: f64) -> f64 { let x1p_120f = f64::from_bits(0x3870000000000000); // 0x1p-120 === 2 ^ -120 let z: f64; diff --git a/src/math/acosf.rs b/src/math/acosf.rs index c54c2c6a5..d0598e811 100644 --- a/src/math/acosf.rs +++ b/src/math/acosf.rs @@ -14,8 +14,6 @@ */ use super::sqrtf::sqrtf; -#[cfg(test)] -use libm_test::libm_test; const PIO2_HI: f32 = 1.5707962513e+00; /* 0x3fc90fda */ const PIO2_LO: f32 = 7.5497894159e-08; /* 0x33a22168 */ @@ -38,7 +36,6 @@ fn r(z: f32) -> f32 { /// Returns values in radians, in the range of 0 to pi. #[inline] #[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)] -#[cfg_attr(test, libm_test)] pub fn acosf(x: f32) -> f32 { let x1p_120 = f32::from_bits(0x03800000); // 0x1p-120 === 2 ^ (-120) diff --git a/src/math/acosh.rs b/src/math/acosh.rs index ff0be2e77..ac7a5f1c6 100644 --- a/src/math/acosh.rs +++ b/src/math/acosh.rs @@ -1,6 +1,4 @@ use super::{log, log1p, sqrt}; -#[cfg(test)] -use libm_test::libm_test; const LN2: f64 = 0.693147180559945309417232121458176568; /* 0x3fe62e42, 0xfefa39ef*/ @@ -9,7 +7,6 @@ const LN2: f64 = 0.693147180559945309417232121458176568; /* 0x3fe62e42, 0xfefa3 /// Calculates the inverse hyperbolic cosine of `x`. /// Is defined as `log(x + sqrt(x*x-1))`. /// `x` must be a number greater than or equal to 1. -#[cfg_attr(test, libm_test)] pub fn acosh(x: f64) -> f64 { let u = x.to_bits(); let e = ((u >> 52) as usize) & 0x7ff; diff --git a/src/math/acoshf.rs b/src/math/acoshf.rs index e01c592e6..0879e1edb 100644 --- a/src/math/acoshf.rs +++ b/src/math/acoshf.rs @@ -1,6 +1,4 @@ use super::{log1pf, logf, sqrtf}; -#[cfg(test)] -use libm_test::libm_test; const LN2: f32 = 0.693147180559945309417232121458176568; @@ -9,7 +7,6 @@ const LN2: f32 = 0.693147180559945309417232121458176568; /// Calculates the inverse hyperbolic cosine of `x`. /// Is defined as `log(x + sqrt(x*x-1))`. /// `x` must be a number greater than or equal to 1. -#[cfg_attr(test, libm_test)] pub fn acoshf(x: f32) -> f32 { let u = x.to_bits(); let a = u & 0x7fffffff; diff --git a/src/math/asin.rs b/src/math/asin.rs index fdc50df8f..774475e51 100644 --- a/src/math/asin.rs +++ b/src/math/asin.rs @@ -40,8 +40,6 @@ */ use super::{fabs, get_high_word, get_low_word, sqrt, with_set_low_word}; -#[cfg(test)] -use libm_test::libm_test; const PIO2_HI: f64 = 1.57079632679489655800e+00; /* 0x3FF921FB, 0x54442D18 */ const PIO2_LO: f64 = 6.12323399573676603587e-17; /* 0x3C91A626, 0x33145C07 */ @@ -71,7 +69,6 @@ fn comp_r(z: f64) -> f64 { /// Returns values in radians, in the range of -pi/2 to pi/2. #[inline] #[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)] -#[cfg_attr(test, libm_test)] pub fn asin(mut x: f64) -> f64 { let z: f64; let r: f64; diff --git a/src/math/asinf.rs b/src/math/asinf.rs index 8ccd1de3e..ce0f4a997 100644 --- a/src/math/asinf.rs +++ b/src/math/asinf.rs @@ -15,8 +15,6 @@ use super::fabsf::fabsf; use super::sqrt::sqrt; -#[cfg(test)] -use libm_test::libm_test; const PIO2: f64 = 1.570796326794896558e+00; @@ -40,7 +38,6 @@ fn r(z: f32) -> f32 { /// Returns values in radians, in the range of -pi/2 to pi/2. #[inline] #[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)] -#[cfg_attr(test, libm_test)] pub fn asinf(mut x: f32) -> f32 { let x1p_120 = f64::from_bits(0x3870000000000000); // 0x1p-120 === 2 ^ (-120) diff --git a/src/math/asinh.rs b/src/math/asinh.rs index d8b6da113..14295357a 100644 --- a/src/math/asinh.rs +++ b/src/math/asinh.rs @@ -1,6 +1,4 @@ use super::{log, log1p, sqrt}; -#[cfg(test)] -use libm_test::libm_test; const LN2: f64 = 0.693147180559945309417232121458176568; /* 0x3fe62e42, 0xfefa39ef*/ @@ -9,7 +7,6 @@ const LN2: f64 = 0.693147180559945309417232121458176568; /* 0x3fe62e42, 0xfefa3 /// /// Calculates the inverse hyperbolic sine of `x`. /// Is defined as `sgn(x)*log(|x|+sqrt(x*x+1))`. -#[cfg_attr(test, libm_test)] pub fn asinh(mut x: f64) -> f64 { let mut u = x.to_bits(); let e = ((u >> 52) as usize) & 0x7ff; diff --git a/src/math/asinhf.rs b/src/math/asinhf.rs index f15eba744..e22a29132 100644 --- a/src/math/asinhf.rs +++ b/src/math/asinhf.rs @@ -1,6 +1,4 @@ use super::{log1pf, logf, sqrtf}; -#[cfg(test)] -use libm_test::libm_test; const LN2: f32 = 0.693147180559945309417232121458176568; @@ -9,7 +7,6 @@ const LN2: f32 = 0.693147180559945309417232121458176568; /// /// Calculates the inverse hyperbolic sine of `x`. /// Is defined as `sgn(x)*log(|x|+sqrt(x*x+1))`. -#[cfg_attr(test, libm_test)] pub fn asinhf(mut x: f32) -> f32 { let u = x.to_bits(); let i = u & 0x7fffffff; diff --git a/src/math/atan.rs b/src/math/atan.rs index 772c045fc..d2684ece8 100644 --- a/src/math/atan.rs +++ b/src/math/atan.rs @@ -31,8 +31,6 @@ use super::fabs; use core::f64; -#[cfg(test)] -use libm_test::libm_test; const ATANHI: [f64; 4] = [ 4.63647609000806093515e-01, /* atan(0.5)hi 0x3FDDAC67, 0x0561BB4F */ @@ -68,7 +66,6 @@ const AT: [f64; 11] = [ /// Returns a value in radians, in the range of -pi/2 to pi/2. #[inline] #[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)] -#[cfg_attr(test, libm_test)] pub fn atan(x: f64) -> f64 { let mut x = x; let mut ix = (x.to_bits() >> 32) as u32; diff --git a/src/math/atan2.rs b/src/math/atan2.rs index 07cc1f4cb..08385cd10 100644 --- a/src/math/atan2.rs +++ b/src/math/atan2.rs @@ -39,8 +39,6 @@ use super::atan; use super::fabs; -#[cfg(test)] -use libm_test::libm_test; const PI: f64 = 3.1415926535897931160E+00; /* 0x400921FB, 0x54442D18 */ const PI_LO: f64 = 1.2246467991473531772E-16; /* 0x3CA1A626, 0x33145C07 */ @@ -52,7 +50,6 @@ const PI_LO: f64 = 1.2246467991473531772E-16; /* 0x3CA1A626, 0x33145C07 */ /// Returns a value in radians, in the range of -pi to pi. #[inline] #[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)] -#[cfg_attr(test, libm_test)] pub fn atan2(y: f64, x: f64) -> f64 { if x.is_nan() || y.is_nan() { return x + y; diff --git a/src/math/atan2f.rs b/src/math/atan2f.rs index e173dcd13..7bbe5f1d4 100644 --- a/src/math/atan2f.rs +++ b/src/math/atan2f.rs @@ -15,8 +15,6 @@ use super::atanf; use super::fabsf; -#[cfg(test)] -use libm_test::libm_test; const PI: f32 = 3.1415927410e+00; /* 0x40490fdb */ const PI_LO: f32 = -8.7422776573e-08; /* 0xb3bbbd2e */ @@ -28,7 +26,6 @@ const PI_LO: f32 = -8.7422776573e-08; /* 0xb3bbbd2e */ /// Returns a value in radians, in the range of -pi to pi. #[inline] #[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)] -#[cfg_attr(test, libm_test)] pub fn atan2f(y: f32, x: f32) -> f32 { if x.is_nan() || y.is_nan() { return x + y; diff --git a/src/math/atanf.rs b/src/math/atanf.rs index efe5de289..363e11d64 100644 --- a/src/math/atanf.rs +++ b/src/math/atanf.rs @@ -14,8 +14,6 @@ */ use super::fabsf; -#[cfg(test)] -use libm_test::libm_test; const ATAN_HI: [f32; 4] = [ 4.6364760399e-01, /* atan(0.5)hi 0x3eed6338 */ @@ -45,7 +43,6 @@ const A_T: [f32; 5] = [ /// Returns a value in radians, in the range of -pi/2 to pi/2. #[inline] #[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)] -#[cfg_attr(test, libm_test)] pub fn atanf(mut x: f32) -> f32 { let x1p_120 = f32::from_bits(0x03800000); // 0x1p-120 === 2 ^ (-120) diff --git a/src/math/atanh.rs b/src/math/atanh.rs index 772b094db..79a989c42 100644 --- a/src/math/atanh.rs +++ b/src/math/atanh.rs @@ -1,13 +1,10 @@ use super::log1p; -#[cfg(test)] -use libm_test::libm_test; /* atanh(x) = log((1+x)/(1-x))/2 = log1p(2x/(1-x))/2 ~= x + x^3/3 + o(x^5) */ /// Inverse hyperbolic tangent (f64) /// /// Calculates the inverse hyperbolic tangent of `x`. /// Is defined as `log((1+x)/(1-x))/2 = log1p(2x/(1-x))/2`. -#[cfg_attr(test, libm_test)] pub fn atanh(x: f64) -> f64 { let u = x.to_bits(); let e = ((u >> 52) as usize) & 0x7ff; diff --git a/src/math/atanhf.rs b/src/math/atanhf.rs index 3b61bb4e5..7b2f34d97 100644 --- a/src/math/atanhf.rs +++ b/src/math/atanhf.rs @@ -1,13 +1,10 @@ use super::log1pf; -#[cfg(test)] -use libm_test::libm_test; /* atanh(x) = log((1+x)/(1-x))/2 = log1p(2x/(1-x))/2 ~= x + x^3/3 + o(x^5) */ /// Inverse hyperbolic tangent (f32) /// /// Calculates the inverse hyperbolic tangent of `x`. /// Is defined as `log((1+x)/(1-x))/2 = log1p(2x/(1-x))/2`. -#[cfg_attr(test, libm_test)] pub fn atanhf(mut x: f32) -> f32 { let mut u = x.to_bits(); let sign = (u >> 31) != 0; diff --git a/src/math/cbrt.rs b/src/math/cbrt.rs index f07779dd9..04469b159 100644 --- a/src/math/cbrt.rs +++ b/src/math/cbrt.rs @@ -16,8 +16,6 @@ */ use core::f64; -#[cfg(test)] -use libm_test::libm_test; const B1: u32 = 715094163; /* B1 = (1023-1023/3-0.03306235651)*2**20 */ const B2: u32 = 696219795; /* B2 = (1023-1023/3-54/3-0.03306235651)*2**20 */ @@ -34,7 +32,6 @@ const P4: f64 = 0.145996192886612446982; /* 0x3fc2b000, 0xd4e4edd7 */ /// Computes the cube root of the argument. #[inline] #[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)] -#[cfg_attr(test, libm_test)] pub fn cbrt(x: f64) -> f64 { let x1p54 = f64::from_bits(0x4350000000000000); // 0x1p54 === 2 ^ 54 diff --git a/src/math/cbrtf.rs b/src/math/cbrtf.rs index f86827f9b..6e589c099 100644 --- a/src/math/cbrtf.rs +++ b/src/math/cbrtf.rs @@ -18,8 +18,6 @@ */ use core::f32; -#[cfg(test)] -use libm_test::libm_test; const B1: u32 = 709958130; /* B1 = (127-127.0/3-0.03306235651)*2**23 */ const B2: u32 = 642849266; /* B2 = (127-127.0/3-24/3-0.03306235651)*2**23 */ @@ -29,7 +27,6 @@ const B2: u32 = 642849266; /* B2 = (127-127.0/3-24/3-0.03306235651)*2**23 */ /// Computes the cube root of the argument. #[inline] #[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)] -#[cfg_attr(test, libm_test)] pub fn cbrtf(x: f32) -> f32 { let x1p24 = f32::from_bits(0x4b800000); // 0x1p24f === 2 ^ 24 diff --git a/src/math/ceil.rs b/src/math/ceil.rs index ad0eefcdb..59883a8a7 100644 --- a/src/math/ceil.rs +++ b/src/math/ceil.rs @@ -1,6 +1,4 @@ use core::f64; -#[cfg(test)] -use libm_test::libm_test; const TOINT: f64 = 1. / f64::EPSILON; @@ -9,7 +7,6 @@ const TOINT: f64 = 1. / f64::EPSILON; /// Finds the nearest integer greater than or equal to `x`. #[inline] #[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)] -#[cfg_attr(test, libm_test)] pub fn ceil(x: f64) -> f64 { // On wasm32 we know that LLVM's intrinsic will compile to an optimized // `f64.ceil` native instruction, so we can leverage this for both code size diff --git a/src/math/ceilf.rs b/src/math/ceilf.rs index 517f1ebc5..151a4f210 100644 --- a/src/math/ceilf.rs +++ b/src/math/ceilf.rs @@ -1,13 +1,10 @@ use core::f32; -#[cfg(test)] -use libm_test::libm_test; /// Ceil (f32) /// /// Finds the nearest integer greater than or equal to `x`. #[inline] #[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)] -#[cfg_attr(test, libm_test)] pub fn ceilf(x: f32) -> f32 { // On wasm32 we know that LLVM's intrinsic will compile to an optimized // `f32.ceil` native instruction, so we can leverage this for both code size diff --git a/src/math/copysign.rs b/src/math/copysign.rs index 0e6b1395f..1527fb6ea 100644 --- a/src/math/copysign.rs +++ b/src/math/copysign.rs @@ -1,11 +1,7 @@ -#[cfg(test)] -use libm_test::libm_test; - /// Sign of Y, magnitude of X (f64) /// /// Constructs a number with the magnitude (absolute value) of its /// first argument, `x`, and the sign of its second argument, `y`. -#[cfg_attr(test, libm_test)] pub fn copysign(x: f64, y: f64) -> f64 { let mut ux = x.to_bits(); let uy = y.to_bits(); diff --git a/src/math/copysignf.rs b/src/math/copysignf.rs index 81d66beb7..35148561a 100644 --- a/src/math/copysignf.rs +++ b/src/math/copysignf.rs @@ -1,11 +1,7 @@ -#[cfg(test)] -use libm_test::libm_test; - /// Sign of Y, magnitude of X (f32) /// /// Constructs a number with the magnitude (absolute value) of its /// first argument, `x`, and the sign of its second argument, `y`. -#[cfg_attr(test, libm_test)] pub fn copysignf(x: f32, y: f32) -> f32 { let mut ux = x.to_bits(); let uy = y.to_bits(); diff --git a/src/math/cos.rs b/src/math/cos.rs index b7ed65515..fe5a89919 100644 --- a/src/math/cos.rs +++ b/src/math/cos.rs @@ -10,8 +10,6 @@ // ==================================================== use super::{k_cos, k_sin, rem_pio2}; -#[cfg(test)] -use libm_test::libm_test; // cos(x) // Return cosine function of x. @@ -45,7 +43,6 @@ use libm_test::libm_test; // #[inline] #[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)] -#[cfg_attr(test, libm_test)] pub fn cos(x: f64) -> f64 { let ix = (f64::to_bits(x) >> 32) as u32 & 0x7fffffff; diff --git a/src/math/cosf.rs b/src/math/cosf.rs index c5c73af92..48d76c8ee 100644 --- a/src/math/cosf.rs +++ b/src/math/cosf.rs @@ -15,8 +15,6 @@ */ use super::{k_cosf, k_sinf, rem_pio2f}; -#[cfg(test)] -use libm_test::libm_test; use core::f64::consts::FRAC_PI_2; @@ -28,7 +26,6 @@ const C4_PIO2: f64 = 4. * FRAC_PI_2; /* 0x401921FB, 0x54442D18 */ #[inline] #[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)] -#[cfg_attr(test, libm_test)] pub fn cosf(x: f32) -> f32 { let x64 = x as f64; diff --git a/src/math/cosh.rs b/src/math/cosh.rs index e3faecff1..bac875566 100644 --- a/src/math/cosh.rs +++ b/src/math/cosh.rs @@ -1,8 +1,6 @@ use super::exp; use super::expm1; use super::k_expo2; -#[cfg(test)] -use libm_test::libm_test; /// Hyperbolic cosine (f64) /// @@ -11,7 +9,6 @@ use libm_test::libm_test; /// Angles are specified in radians. #[inline] #[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)] -#[cfg_attr(test, libm_test)] pub fn cosh(mut x: f64) -> f64 { /* |x| */ let mut ix = x.to_bits(); diff --git a/src/math/coshf.rs b/src/math/coshf.rs index 5c285c271..bf99e42f0 100644 --- a/src/math/coshf.rs +++ b/src/math/coshf.rs @@ -1,8 +1,6 @@ use super::expf; use super::expm1f; use super::k_expo2f; -#[cfg(test)] -use libm_test::libm_test; /// Hyperbolic cosine (f64) /// @@ -11,7 +9,6 @@ use libm_test::libm_test; /// Angles are specified in radians. #[inline] #[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)] -#[cfg_attr(test, libm_test)] pub fn coshf(mut x: f32) -> f32 { let x1p120 = f32::from_bits(0x7b800000); // 0x1p120f === 2 ^ 120 diff --git a/src/math/erf.rs b/src/math/erf.rs index 69e062580..a2c617d34 100644 --- a/src/math/erf.rs +++ b/src/math/erf.rs @@ -1,6 +1,4 @@ use super::{exp, fabs, get_high_word, with_set_low_word}; -#[cfg(test)] -use libm_test::libm_test; /* origin: FreeBSD /usr/src/lib/msun/src/s_erf.c */ /* * ==================================================== @@ -221,7 +219,6 @@ fn erfc2(ix: u32, mut x: f64) -> f64 { /// Calculates an approximation to the “error function”, which estimates /// the probability that an observation will fall within x standard /// deviations of the mean (assuming a normal distribution). -#[cfg_attr(test, libm_test)] pub fn erf(x: f64) -> f64 { let r: f64; let s: f64; diff --git a/src/math/erff.rs b/src/math/erff.rs index 3d0c3fda9..384052293 100644 --- a/src/math/erff.rs +++ b/src/math/erff.rs @@ -14,8 +14,6 @@ */ use super::{expf, fabsf}; -#[cfg(test)] -use libm_test::libm_test; const ERX: f32 = 8.4506291151e-01; /* 0x3f58560b */ /* @@ -132,7 +130,6 @@ fn erfc2(mut ix: u32, mut x: f32) -> f32 { /// Calculates an approximation to the “error function”, which estimates /// the probability that an observation will fall within x standard /// deviations of the mean (assuming a normal distribution). -#[cfg_attr(test, libm_test)] pub fn erff(x: f32) -> f32 { let r: f32; let s: f32; diff --git a/src/math/exp.rs b/src/math/exp.rs index 97958de4c..5465b5693 100644 --- a/src/math/exp.rs +++ b/src/math/exp.rs @@ -66,8 +66,6 @@ */ use super::scalbn; -#[cfg(test)] -use libm_test::libm_test; const HALF: [f64; 2] = [0.5, -0.5]; const LN2HI: f64 = 6.93147180369123816490e-01; /* 0x3fe62e42, 0xfee00000 */ @@ -85,7 +83,6 @@ const P5: f64 = 4.13813679705723846039e-08; /* 0x3E663769, 0x72BEA4D0 */ /// (where *e* is the base of the natural system of logarithms, approximately 2.71828). #[inline] #[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)] -#[cfg_attr(test, libm_test)] pub fn exp(mut x: f64) -> f64 { let x1p1023 = f64::from_bits(0x7fe0000000000000); // 0x1p1023 === 2 ^ 1023 let x1p_149 = f64::from_bits(0x36a0000000000000); // 0x1p-149 === 2 ^ -149 diff --git a/src/math/exp10.rs b/src/math/exp10.rs index 213fc0f5b..9537f76f1 100644 --- a/src/math/exp10.rs +++ b/src/math/exp10.rs @@ -1,6 +1,4 @@ use super::{exp2, modf, pow}; -#[cfg(test)] -use libm_test::libm_test; const LN10: f64 = 3.32192809488736234787031942948939; const P10: &[f64] = &[ @@ -8,7 +6,6 @@ const P10: &[f64] = &[ 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, ]; -#[cfg_attr(test, libm_test)] pub fn exp10(x: f64) -> f64 { let (mut y, n) = modf(x); let u: u64 = n.to_bits(); diff --git a/src/math/exp10f.rs b/src/math/exp10f.rs index f0c4b2490..d45fff36e 100644 --- a/src/math/exp10f.rs +++ b/src/math/exp10f.rs @@ -1,6 +1,4 @@ use super::{exp2, exp2f, modff}; -#[cfg(test)] -use libm_test::libm_test; const LN10_F32: f32 = 3.32192809488736234787031942948939; const LN10_F64: f64 = 3.32192809488736234787031942948939; @@ -8,7 +6,6 @@ const P10: &[f32] = &[ 1e-7, 1e-6, 1e-5, 1e-4, 1e-3, 1e-2, 1e-1, 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, ]; -#[cfg_attr(test, libm_test)] pub fn exp10f(x: f32) -> f32 { let (mut y, n) = modff(x); let u = n.to_bits(); diff --git a/src/math/exp2.rs b/src/math/exp2.rs index 502593d80..c2192fde5 100644 --- a/src/math/exp2.rs +++ b/src/math/exp2.rs @@ -25,8 +25,6 @@ // SUCH DAMAGE. use super::scalbn; -#[cfg(test)] -use libm_test::libm_test; const TBLSIZE: usize = 256; @@ -326,7 +324,6 @@ static TBL: [u64; TBLSIZE * 2] = [ /// Calculate `2^x`, that is, 2 raised to the power `x`. #[inline] #[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)] -#[cfg_attr(test, libm_test)] pub fn exp2(mut x: f64) -> f64 { let redux = f64::from_bits(0x4338000000000000) / TBLSIZE as f64; let p1 = f64::from_bits(0x3fe62e42fefa39ef); diff --git a/src/math/exp2f.rs b/src/math/exp2f.rs index 6cd662b36..12c9e76a4 100644 --- a/src/math/exp2f.rs +++ b/src/math/exp2f.rs @@ -24,8 +24,6 @@ // OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF // SUCH DAMAGE. -#[cfg(test)] -use libm_test::libm_test; const TBLSIZE: usize = 16; static EXP2FT: [u64; TBLSIZE] = [ @@ -77,7 +75,6 @@ static EXP2FT: [u64; TBLSIZE] = [ /// Calculate `2^x`, that is, 2 raised to the power `x`. #[inline] #[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)] -#[cfg_attr(test, libm_test)] pub fn exp2f(mut x: f32) -> f32 { let redux = f32::from_bits(0x4b400000) / TBLSIZE as f32; let p1 = f32::from_bits(0x3f317218); diff --git a/src/math/expf.rs b/src/math/expf.rs index df829ad58..09323ec8d 100644 --- a/src/math/expf.rs +++ b/src/math/expf.rs @@ -14,8 +14,6 @@ */ use super::scalbnf; -#[cfg(test)] -use libm_test::libm_test; const HALF: [f32; 2] = [0.5, -0.5]; const LN2_HI: f32 = 6.9314575195e-01; /* 0x3f317200 */ @@ -34,7 +32,6 @@ const P2: f32 = -2.7667332906e-3; /* -0xb55215.0p-32 */ /// (where *e* is the base of the natural system of logarithms, approximately 2.71828). #[inline] #[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)] -#[cfg_attr(test, libm_test)] pub fn expf(mut x: f32) -> f32 { let x1p127 = f32::from_bits(0x7f000000); // 0x1p127f === 2 ^ 127 let x1p_126 = f32::from_bits(0x800000); // 0x1p-126f === 2 ^ -126 /*original 0x1p-149f ??????????? */ diff --git a/src/math/expm1.rs b/src/math/expm1.rs index 0ec77080c..0d43b4e10 100644 --- a/src/math/expm1.rs +++ b/src/math/expm1.rs @@ -11,8 +11,6 @@ */ use core::f64; -#[cfg(test)] -use libm_test::libm_test; const O_THRESHOLD: f64 = 7.09782712893383973096e+02; /* 0x40862E42, 0xFEFA39EF */ const LN2_HI: f64 = 6.93147180369123816490e-01; /* 0x3fe62e42, 0xfee00000 */ @@ -34,7 +32,6 @@ const Q5: f64 = -2.01099218183624371326e-07; /* BE8AFDB7 6E09C32D */ /// where using `exp(x)-1` would lose many significant digits. #[inline] #[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)] -#[cfg_attr(test, libm_test)] pub fn expm1(mut x: f64) -> f64 { let hi: f64; let lo: f64; diff --git a/src/math/expm1f.rs b/src/math/expm1f.rs index b13757d14..9bb223448 100644 --- a/src/math/expm1f.rs +++ b/src/math/expm1f.rs @@ -13,8 +13,6 @@ * ==================================================== */ -#[cfg(test)] -use libm_test::libm_test; const O_THRESHOLD: f32 = 8.8721679688e+01; /* 0x42b17180 */ const LN2_HI: f32 = 6.9313812256e-01; /* 0x3f317180 */ const LN2_LO: f32 = 9.0580006145e-06; /* 0x3717f7d1 */ @@ -36,7 +34,6 @@ const Q2: f32 = 1.5807170421e-3; /* 0xcf3010.0p-33 */ /// where using `exp(x)-1` would lose many significant digits. #[inline] #[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)] -#[cfg_attr(test, libm_test)] pub fn expm1f(mut x: f32) -> f32 { let x1p127 = f32::from_bits(0x7f000000); // 0x1p127f === 2 ^ 127 diff --git a/src/math/expo2.rs b/src/math/expo2.rs index 696a3e5ff..ae6cc8121 100644 --- a/src/math/expo2.rs +++ b/src/math/expo2.rs @@ -1,11 +1,8 @@ use super::{combine_words, exp}; -#[cfg(test)] -use libm_test::libm_test; /* exp(x)/2 for x >= log(DBL_MAX), slightly better than 0.5*exp(x/2)*exp(x/2) */ #[inline] #[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)] -#[cfg_attr(test, libm_test)] pub(crate) fn expo2(x: f64) -> f64 { /* k is such that k*ln2 has minimal relative error and x - kln2 > log(DBL_MIN) */ const K: i32 = 2043; diff --git a/src/math/fabs.rs b/src/math/fabs.rs index 2f8f19df4..52a9adcbf 100644 --- a/src/math/fabs.rs +++ b/src/math/fabs.rs @@ -1,13 +1,10 @@ use core::u64; -#[cfg(test)] -use libm_test::libm_test; /// Absolute value (magnitude) (f64) /// Calculates the absolute value (magnitude) of the argument `x`, /// by direct manipulation of the bit representation of `x`. #[inline] #[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)] -#[cfg_attr(test, libm_test)] pub fn fabs(x: f64) -> f64 { // On wasm32 we know that LLVM's intrinsic will compile to an optimized // `f64.abs` native instruction, so we can leverage this for both code size diff --git a/src/math/fabsf.rs b/src/math/fabsf.rs index c3316e41f..5942d983a 100644 --- a/src/math/fabsf.rs +++ b/src/math/fabsf.rs @@ -1,12 +1,8 @@ -#[cfg(test)] -use libm_test::libm_test; - /// Absolute value (magnitude) (f32) /// Calculates the absolute value (magnitude) of the argument `x`, /// by direct manipulation of the bit representation of `x`. #[inline] #[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)] -#[cfg_attr(test, libm_test)] pub fn fabsf(x: f32) -> f32 { // On wasm32 we know that LLVM's intrinsic will compile to an optimized // `f32.abs` native instruction, so we can leverage this for both code size diff --git a/src/math/fdim.rs b/src/math/fdim.rs index 047e00229..06edc9960 100644 --- a/src/math/fdim.rs +++ b/src/math/fdim.rs @@ -1,6 +1,4 @@ use core::f64; -#[cfg(test)] -use libm_test::libm_test; /// Positive difference (f64) /// @@ -12,7 +10,6 @@ use libm_test::libm_test; /// A range error may occur. #[inline] #[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)] -#[cfg_attr(test, libm_test)] pub fn fdim(x: f64, y: f64) -> f64 { if x.is_nan() { x diff --git a/src/math/fdimf.rs b/src/math/fdimf.rs index 56e88c8f9..f1ad5896b 100644 --- a/src/math/fdimf.rs +++ b/src/math/fdimf.rs @@ -1,6 +1,4 @@ use core::f32; -#[cfg(test)] -use libm_test::libm_test; /// Positive difference (f32) /// @@ -12,7 +10,6 @@ use libm_test::libm_test; /// A range error may occur. #[inline] #[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)] -#[cfg_attr(test, libm_test)] pub fn fdimf(x: f32, y: f32) -> f32 { if x.is_nan() { x diff --git a/src/math/floor.rs b/src/math/floor.rs index 64340b788..f6068c697 100644 --- a/src/math/floor.rs +++ b/src/math/floor.rs @@ -1,6 +1,4 @@ use core::f64; -#[cfg(test)] -use libm_test::libm_test; const TOINT: f64 = 1. / f64::EPSILON; @@ -9,7 +7,6 @@ const TOINT: f64 = 1. / f64::EPSILON; /// Finds the nearest integer less than or equal to `x`. #[inline] #[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)] -#[cfg_attr(test, libm_test)] pub fn floor(x: f64) -> f64 { // On wasm32 we know that LLVM's intrinsic will compile to an optimized // `f64.floor` native instruction, so we can leverage this for both code size diff --git a/src/math/floorf.rs b/src/math/floorf.rs index 1e81ebdea..c04f18aee 100644 --- a/src/math/floorf.rs +++ b/src/math/floorf.rs @@ -1,13 +1,10 @@ use core::f32; -#[cfg(test)] -use libm_test::libm_test; /// Floor (f32) /// /// Finds the nearest integer less than or equal to `x`. #[inline] #[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)] -#[cfg_attr(test, libm_test)] pub fn floorf(x: f32) -> f32 { // On wasm32 we know that LLVM's intrinsic will compile to an optimized // `f32.floor` native instruction, so we can leverage this for both code size diff --git a/src/math/fma.rs b/src/math/fma.rs index f55557b87..07d90f8b7 100644 --- a/src/math/fma.rs +++ b/src/math/fma.rs @@ -1,6 +1,4 @@ use core::{f32, f64}; -#[cfg(test)] -use libm_test::libm_test; use super::scalbn; @@ -57,7 +55,6 @@ fn mul(x: u64, y: u64) -> (u64, u64) { /// according to the rounding mode characterized by the value of FLT_ROUNDS. #[inline] #[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)] -#[cfg_attr(test, libm_test)] pub fn fma(x: f64, y: f64, z: f64) -> f64 { let x1p63: f64 = f64::from_bits(0x43e0000000000000); // 0x1p63 === 2 ^ 63 let x0_ffffff8p_63 = f64::from_bits(0x3bfffffff0000000); // 0x0.ffffff8p-63 diff --git a/src/math/fmaf.rs b/src/math/fmaf.rs index 7106cb48c..e77e0fa4a 100644 --- a/src/math/fmaf.rs +++ b/src/math/fmaf.rs @@ -27,8 +27,6 @@ use core::f32; use core::ptr::read_volatile; -#[cfg(test)] -use libm_test::libm_test; use super::fenv::{ feclearexcept, fegetround, feraiseexcept, fesetround, fetestexcept, FE_INEXACT, FE_TONEAREST, @@ -50,7 +48,6 @@ use super::fenv::{ /// according to the rounding mode characterized by the value of FLT_ROUNDS. #[inline] #[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)] -#[cfg_attr(test, libm_test)] pub fn fmaf(x: f32, y: f32, mut z: f32) -> f32 { let xy: f64; let mut result: f64; diff --git a/src/math/fmax.rs b/src/math/fmax.rs index acf0a51aa..22016d11c 100644 --- a/src/math/fmax.rs +++ b/src/math/fmax.rs @@ -1,9 +1,5 @@ -#[cfg(test)] -use libm_test::libm_test; - #[inline] #[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)] -#[cfg_attr(test, libm_test)] pub fn fmax(x: f64, y: f64) -> f64 { // IEEE754 says: maxNum(x, y) is the canonicalized number y if x < y, x if y < x, the // canonicalized number if one operand is a number and the other a quiet NaN. Otherwise it diff --git a/src/math/fmaxf.rs b/src/math/fmaxf.rs index f205a3966..a883fdaef 100644 --- a/src/math/fmaxf.rs +++ b/src/math/fmaxf.rs @@ -1,9 +1,5 @@ -#[cfg(test)] -use libm_test::libm_test; - #[inline] #[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)] -#[cfg_attr(test, libm_test)] pub fn fmaxf(x: f32, y: f32) -> f32 { // IEEE754 says: maxNum(x, y) is the canonicalized number y if x < y, x if y < x, the // canonicalized number if one operand is a number and the other a quiet NaN. Otherwise it diff --git a/src/math/fmin.rs b/src/math/fmin.rs index 4eccf3479..d1ccc3a46 100644 --- a/src/math/fmin.rs +++ b/src/math/fmin.rs @@ -1,9 +1,5 @@ -#[cfg(test)] -use libm_test::libm_test; - #[inline] #[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)] -#[cfg_attr(test, libm_test)] pub fn fmin(x: f64, y: f64) -> f64 { // IEEE754 says: minNum(x, y) is the canonicalized number x if x < y, y if y < x, the // canonicalized number if one operand is a number and the other a quiet NaN. Otherwise it diff --git a/src/math/fminf.rs b/src/math/fminf.rs index 2e99c9f45..43ec97cb5 100644 --- a/src/math/fminf.rs +++ b/src/math/fminf.rs @@ -1,9 +1,5 @@ -#[cfg(test)] -use libm_test::libm_test; - #[inline] #[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)] -#[cfg_attr(test, libm_test)] pub fn fminf(x: f32, y: f32) -> f32 { // IEEE754 says: minNum(x, y) is the canonicalized number x if x < y, y if y < x, the // canonicalized number if one operand is a number and the other a quiet NaN. Otherwise it diff --git a/src/math/fmod.rs b/src/math/fmod.rs index 0e78cfe28..2cdd8a9ba 100644 --- a/src/math/fmod.rs +++ b/src/math/fmod.rs @@ -1,10 +1,7 @@ use core::u64; -#[cfg(test)] -use libm_test::libm_test; #[inline] #[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)] -#[cfg_attr(test, libm_test)] pub fn fmod(x: f64, y: f64) -> f64 { let mut uxi = x.to_bits(); let mut uyi = y.to_bits(); diff --git a/src/math/fmodf.rs b/src/math/fmodf.rs index 092a5a30f..3e6779a93 100644 --- a/src/math/fmodf.rs +++ b/src/math/fmodf.rs @@ -1,11 +1,8 @@ use core::f32; use core::u32; -#[cfg(test)] -use libm_test::libm_test; #[inline] #[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)] -#[cfg_attr(test, libm_test)] pub fn fmodf(x: f32, y: f32) -> f32 { let mut uxi = x.to_bits(); let mut uyi = y.to_bits(); diff --git a/src/math/frexp.rs b/src/math/frexp.rs index 5b57dbad0..badad786a 100644 --- a/src/math/frexp.rs +++ b/src/math/frexp.rs @@ -1,7 +1,3 @@ -#[cfg(test)] -use libm_test::libm_test; - -#[cfg_attr(test, libm_test)] pub fn frexp(x: f64) -> (f64, i32) { let mut y = x.to_bits(); let ee = ((y >> 52) & 0x7ff) as i32; diff --git a/src/math/frexpf.rs b/src/math/frexpf.rs index 2ddc7e7e6..2919c0ab0 100644 --- a/src/math/frexpf.rs +++ b/src/math/frexpf.rs @@ -1,7 +1,3 @@ -#[cfg(test)] -use libm_test::libm_test; - -#[cfg_attr(test, libm_test)] pub fn frexpf(x: f32) -> (f32, i32) { let mut y = x.to_bits(); let ee: i32 = ((y >> 23) & 0xff) as i32; diff --git a/src/math/hypot.rs b/src/math/hypot.rs index e386ea97e..e53baf539 100644 --- a/src/math/hypot.rs +++ b/src/math/hypot.rs @@ -1,6 +1,3 @@ -#[cfg(test)] -use libm_test::libm_test; - use core::f64; use super::sqrt; @@ -23,7 +20,6 @@ fn sq(x: f64) -> (f64, f64) { #[inline] #[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)] -#[cfg_attr(test, libm_test)] pub fn hypot(mut x: f64, mut y: f64) -> f64 { let x1p700 = f64::from_bits(0x6bb0000000000000); // 0x1p700 === 2 ^ 700 let x1p_700 = f64::from_bits(0x1430000000000000); // 0x1p-700 === 2 ^ -700 diff --git a/src/math/hypotf.rs b/src/math/hypotf.rs index d612ca6c3..4636b8f1d 100644 --- a/src/math/hypotf.rs +++ b/src/math/hypotf.rs @@ -1,12 +1,9 @@ use core::f32; -#[cfg(test)] -use libm_test::libm_test; use super::sqrtf; #[inline] #[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)] -#[cfg_attr(test, libm_test)] pub fn hypotf(mut x: f32, mut y: f32) -> f32 { let x1p90 = f32::from_bits(0x6c800000); // 0x1p90f === 2 ^ 90 let x1p_90 = f32::from_bits(0x12800000); // 0x1p-90f === 2 ^ -90 diff --git a/src/math/ilogb.rs b/src/math/ilogb.rs index d60371135..0a380b7ef 100644 --- a/src/math/ilogb.rs +++ b/src/math/ilogb.rs @@ -1,10 +1,6 @@ -#[cfg(test)] -use libm_test::libm_test; - const FP_ILOGBNAN: i32 = -1 - 0x7fffffff; const FP_ILOGB0: i32 = FP_ILOGBNAN; -#[cfg_attr(test, libm_test)] pub fn ilogb(x: f64) -> i32 { let mut i: u64 = x.to_bits(); let e = ((i >> 52) & 0x7ff) as i32; diff --git a/src/math/ilogbf.rs b/src/math/ilogbf.rs index f10fbd00f..b384fa4b2 100644 --- a/src/math/ilogbf.rs +++ b/src/math/ilogbf.rs @@ -1,10 +1,6 @@ -#[cfg(test)] -use libm_test::libm_test; - const FP_ILOGBNAN: i32 = -1 - 0x7fffffff; const FP_ILOGB0: i32 = FP_ILOGBNAN; -#[cfg_attr(test, libm_test)] pub fn ilogbf(x: f32) -> i32 { let mut i = x.to_bits(); let e = ((i >> 23) & 0xff) as i32; diff --git a/src/math/j0.rs b/src/math/j0.rs index 41cfcc322..c4258ccca 100644 --- a/src/math/j0.rs +++ b/src/math/j0.rs @@ -55,8 +55,6 @@ */ use super::{cos, fabs, get_high_word, get_low_word, log, sin, sqrt}; -#[cfg(test)] -use libm_test::libm_test; const INVSQRTPI: f64 = 5.64189583547756279280e-01; /* 0x3FE20DD7, 0x50429B6D */ const TPI: f64 = 6.36619772367581382433e-01; /* 0x3FE45F30, 0x6DC9C883 */ @@ -111,7 +109,6 @@ const S02: f64 = 1.16926784663337450260e-04; /* 0x3F1EA6D2, 0xDD57DBF4 */ const S03: f64 = 5.13546550207318111446e-07; /* 0x3EA13B54, 0xCE84D5A9 */ const S04: f64 = 1.16614003333790000205e-09; /* 0x3E1408BC, 0xF4745D8F */ -#[cfg_attr(test, libm_test)] pub fn j0(mut x: f64) -> f64 { let z: f64; let r: f64; @@ -165,7 +162,6 @@ const V02: f64 = 7.60068627350353253702e-05; /* 0x3F13ECBB, 0xF578C6C1 */ const V03: f64 = 2.59150851840457805467e-07; /* 0x3E91642D, 0x7FF202FD */ const V04: f64 = 4.41110311332675467403e-10; /* 0x3DFE5018, 0x3BD6D9EF */ -#[cfg_attr(test, libm_test)] pub fn y0(x: f64) -> f64 { let z: f64; let u: f64; diff --git a/src/math/j0f.rs b/src/math/j0f.rs index 7b8e26eb8..91c03dbbc 100644 --- a/src/math/j0f.rs +++ b/src/math/j0f.rs @@ -14,8 +14,6 @@ */ use super::{cosf, fabsf, logf, sinf, sqrtf}; -#[cfg(test)] -use libm_test::libm_test; const INVSQRTPI: f32 = 5.6418961287e-01; /* 0x3f106ebb */ const TPI: f32 = 6.3661974669e-01; /* 0x3f22f983 */ @@ -64,7 +62,6 @@ const S02: f32 = 1.1692678527e-04; /* 0x38f53697 */ const S03: f32 = 5.1354652442e-07; /* 0x3509daa6 */ const S04: f32 = 1.1661400734e-09; /* 0x30a045e8 */ -#[cfg_attr(test, libm_test)] pub fn j0f(mut x: f32) -> f32 { let z: f32; let r: f32; @@ -110,7 +107,6 @@ const V02: f32 = 7.6006865129e-05; /* 0x389f65e0 */ const V03: f32 = 2.5915085189e-07; /* 0x348b216c */ const V04: f32 = 4.4111031494e-10; /* 0x2ff280c2 */ -#[cfg_attr(test, libm_test)] pub fn y0f(x: f32) -> f32 { let z: f32; let u: f32; diff --git a/src/math/j1.rs b/src/math/j1.rs index 0969cb5ad..02a65ca5a 100644 --- a/src/math/j1.rs +++ b/src/math/j1.rs @@ -55,8 +55,6 @@ */ use super::{cos, fabs, get_high_word, get_low_word, log, sin, sqrt}; -#[cfg(test)] -use libm_test::libm_test; const INVSQRTPI: f64 = 5.64189583547756279280e-01; /* 0x3FE20DD7, 0x50429B6D */ const TPI: f64 = 6.36619772367581382433e-01; /* 0x3FE45F30, 0x6DC9C883 */ @@ -115,7 +113,6 @@ const S03: f64 = 1.17718464042623683263e-06; /* 0x3EB3BFF8, 0x333F8498 */ const S04: f64 = 5.04636257076217042715e-09; /* 0x3E35AC88, 0xC97DFF2C */ const S05: f64 = 1.23542274426137913908e-11; /* 0x3DAB2ACF, 0xCFB97ED8 */ -#[cfg_attr(test, libm_test)] pub fn j1(x: f64) -> f64 { let mut z: f64; let r: f64; @@ -161,7 +158,6 @@ const V0: [f64; 5] = [ 1.66559246207992079114e-11, /* 0x3DB25039, 0xDACA772A */ ]; -#[cfg_attr(test, libm_test)] pub fn y1(x: f64) -> f64 { let z: f64; let u: f64; diff --git a/src/math/j1f.rs b/src/math/j1f.rs index f62b9d9fe..5095894d7 100644 --- a/src/math/j1f.rs +++ b/src/math/j1f.rs @@ -14,8 +14,6 @@ */ use super::{cosf, fabsf, logf, sinf, sqrtf}; -#[cfg(test)] -use libm_test::libm_test; const INVSQRTPI: f32 = 5.6418961287e-01; /* 0x3f106ebb */ const TPI: f32 = 6.3661974669e-01; /* 0x3f22f983 */ @@ -65,7 +63,6 @@ const S03: f32 = 1.1771846857e-06; /* 0x359dffc2 */ const S04: f32 = 5.0463624390e-09; /* 0x31ad6446 */ const S05: f32 = 1.2354227016e-11; /* 0x2d59567e */ -#[cfg_attr(test, libm_test)] pub fn j1f(x: f32) -> f32 { let mut z: f32; let r: f32; @@ -110,7 +107,6 @@ const V0: [f32; 5] = [ 1.6655924903e-11, /* 0x2d9281cf */ ]; -#[cfg_attr(test, libm_test)] pub fn y1f(x: f32) -> f32 { let z: f32; let u: f32; diff --git a/src/math/jn.rs b/src/math/jn.rs index fda025196..1be167f84 100644 --- a/src/math/jn.rs +++ b/src/math/jn.rs @@ -35,12 +35,9 @@ */ use super::{cos, fabs, get_high_word, get_low_word, j0, j1, log, sin, sqrt, y0, y1}; -#[cfg(test)] -use libm_test::libm_test; const INVSQRTPI: f64 = 5.64189583547756279280e-01; /* 0x3FE20DD7, 0x50429B6D */ -#[cfg_attr(test, libm_test)] pub fn jn(n: i32, mut x: f64) -> f64 { let mut ix: u32; let lx: u32; @@ -254,7 +251,6 @@ pub fn jn(n: i32, mut x: f64) -> f64 { } } -#[cfg_attr(test, libm_test)] pub fn yn(n: i32, x: f64) -> f64 { let mut ix: u32; let lx: u32; diff --git a/src/math/jnf.rs b/src/math/jnf.rs index 0dcf88ec7..360f62e20 100644 --- a/src/math/jnf.rs +++ b/src/math/jnf.rs @@ -14,10 +14,7 @@ */ use super::{fabsf, j0f, j1f, logf, y0f, y1f}; -#[cfg(test)] -use libm_test::libm_test; -#[cfg_attr(test, libm_test)] pub fn jnf(n: i32, mut x: f32) -> f32 { let mut ix: u32; let mut nm1: i32; @@ -198,7 +195,6 @@ pub fn jnf(n: i32, mut x: f32) -> f32 { } } -#[cfg_attr(test, libm_test)] pub fn ynf(n: i32, x: f32) -> f32 { let mut ix: u32; let mut ib: u32; diff --git a/src/math/lgamma.rs b/src/math/lgamma.rs index 4e06a2d10..5bc87e85e 100644 --- a/src/math/lgamma.rs +++ b/src/math/lgamma.rs @@ -1,8 +1,5 @@ use super::lgamma_r; -#[cfg(test)] -use libm_test::libm_test; -#[cfg_attr(test, libm_test)] pub fn lgamma(x: f64) -> f64 { lgamma_r(x).0 } diff --git a/src/math/lgammaf.rs b/src/math/lgammaf.rs index 712b51823..dfdc87f96 100644 --- a/src/math/lgammaf.rs +++ b/src/math/lgammaf.rs @@ -1,8 +1,5 @@ use super::lgammaf_r; -#[cfg(test)] -use libm_test::libm_test; -#[cfg_attr(test, libm_test)] pub fn lgammaf(x: f32) -> f32 { lgammaf_r(x).0 } diff --git a/src/math/log.rs b/src/math/log.rs index 684f8112f..4126e413b 100644 --- a/src/math/log.rs +++ b/src/math/log.rs @@ -60,8 +60,6 @@ * to produce the hexadecimal values shown. */ -#[cfg(test)] -use libm_test::libm_test; const LN2_HI: f64 = 6.93147180369123816490e-01; /* 3fe62e42 fee00000 */ const LN2_LO: f64 = 1.90821492927058770002e-10; /* 3dea39ef 35793c76 */ const LG1: f64 = 6.666666666666735130e-01; /* 3FE55555 55555593 */ @@ -74,7 +72,6 @@ const LG7: f64 = 1.479819860511658591e-01; /* 3FC2F112 DF3E5244 */ #[inline] #[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)] -#[cfg_attr(test, libm_test)] pub fn log(mut x: f64) -> f64 { let x1p54 = f64::from_bits(0x4350000000000000); // 0x1p54 === 2 ^ 54 diff --git a/src/math/log10.rs b/src/math/log10.rs index 472fb5355..c99696040 100644 --- a/src/math/log10.rs +++ b/src/math/log10.rs @@ -18,8 +18,6 @@ */ use core::f64; -#[cfg(test)] -use libm_test::libm_test; const IVLN10HI: f64 = 4.34294481878168880939e-01; /* 0x3fdbcb7b, 0x15200000 */ const IVLN10LO: f64 = 2.50829467116452752298e-11; /* 0x3dbb9438, 0xca9aadd5 */ @@ -35,7 +33,6 @@ const LG7: f64 = 1.479819860511658591e-01; /* 3FC2F112 DF3E5244 */ #[inline] #[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)] -#[cfg_attr(test, libm_test)] pub fn log10(mut x: f64) -> f64 { let x1p54 = f64::from_bits(0x4350000000000000); // 0x1p54 === 2 ^ 54 diff --git a/src/math/log10f.rs b/src/math/log10f.rs index 85e01f271..9845cda5d 100644 --- a/src/math/log10f.rs +++ b/src/math/log10f.rs @@ -14,8 +14,6 @@ */ use core::f32; -#[cfg(test)] -use libm_test::libm_test; const IVLN10HI: f32 = 4.3432617188e-01; /* 0x3ede6000 */ const IVLN10LO: f32 = -3.1689971365e-05; /* 0xb804ead9 */ @@ -29,7 +27,6 @@ const LG4: f32 = 0.24279078841; /* 0xf89e26.0p-26 */ #[inline] #[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)] -#[cfg_attr(test, libm_test)] pub fn log10f(mut x: f32) -> f32 { let x1p25f = f32::from_bits(0x4c000000); // 0x1p25f === 2 ^ 25 diff --git a/src/math/log1p.rs b/src/math/log1p.rs index 299ba5b34..cd7045ac9 100644 --- a/src/math/log1p.rs +++ b/src/math/log1p.rs @@ -54,8 +54,6 @@ */ use core::f64; -#[cfg(test)] -use libm_test::libm_test; const LN2_HI: f64 = 6.93147180369123816490e-01; /* 3fe62e42 fee00000 */ const LN2_LO: f64 = 1.90821492927058770002e-10; /* 3dea39ef 35793c76 */ @@ -69,7 +67,6 @@ const LG7: f64 = 1.479819860511658591e-01; /* 3FC2F112 DF3E5244 */ #[inline] #[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)] -#[cfg_attr(test, libm_test)] pub fn log1p(x: f64) -> f64 { let mut ui: u64 = x.to_bits(); let hfsq: f64; diff --git a/src/math/log1pf.rs b/src/math/log1pf.rs index fa797fcba..8e9651357 100644 --- a/src/math/log1pf.rs +++ b/src/math/log1pf.rs @@ -11,8 +11,6 @@ */ use core::f32; -#[cfg(test)] -use libm_test::libm_test; const LN2_HI: f32 = 6.9313812256e-01; /* 0x3f317180 */ const LN2_LO: f32 = 9.0580006145e-06; /* 0x3717f7d1 */ @@ -24,7 +22,6 @@ const LG4: f32 = 0.24279078841; /* 0xf89e26.0p-26 */ #[inline] #[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)] -#[cfg_attr(test, libm_test)] pub fn log1pf(x: f32) -> f32 { let mut ui: u32 = x.to_bits(); let hfsq: f32; diff --git a/src/math/log2.rs b/src/math/log2.rs index 0178cf9d9..a3d43e55c 100644 --- a/src/math/log2.rs +++ b/src/math/log2.rs @@ -18,8 +18,6 @@ */ use core::f64; -#[cfg(test)] -use libm_test::libm_test; const IVLN2HI: f64 = 1.44269504072144627571e+00; /* 0x3ff71547, 0x65200000 */ const IVLN2LO: f64 = 1.67517131648865118353e-10; /* 0x3de705fc, 0x2eefa200 */ @@ -33,7 +31,6 @@ const LG7: f64 = 1.479819860511658591e-01; /* 3FC2F112 DF3E5244 */ #[inline] #[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)] -#[cfg_attr(test, libm_test)] pub fn log2(mut x: f64) -> f64 { let x1p54 = f64::from_bits(0x4350000000000000); // 0x1p54 === 2 ^ 54 diff --git a/src/math/log2f.rs b/src/math/log2f.rs index 4edbd65ba..53a37e503 100644 --- a/src/math/log2f.rs +++ b/src/math/log2f.rs @@ -14,8 +14,6 @@ */ use core::f32; -#[cfg(test)] -use libm_test::libm_test; const IVLN2HI: f32 = 1.4428710938e+00; /* 0x3fb8b000 */ const IVLN2LO: f32 = -1.7605285393e-04; /* 0xb9389ad4 */ @@ -27,7 +25,6 @@ const LG4: f32 = 0.24279078841; /* 0xf89e26.0p-26 */ #[inline] #[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)] -#[cfg_attr(test, libm_test)] pub fn log2f(mut x: f32) -> f32 { let x1p25f = f32::from_bits(0x4c000000); // 0x1p25f === 2 ^ 25 diff --git a/src/math/logf.rs b/src/math/logf.rs index 3d25fdb7c..95195601c 100644 --- a/src/math/logf.rs +++ b/src/math/logf.rs @@ -13,9 +13,6 @@ * ==================================================== */ -#[cfg(test)] -use libm_test::libm_test; - const LN2_HI: f32 = 6.9313812256e-01; /* 0x3f317180 */ const LN2_LO: f32 = 9.0580006145e-06; /* 0x3717f7d1 */ /* |(log(1+s)-log(1-s))/s - Lg(s)| < 2**-34.24 (~[-4.95e-11, 4.97e-11]). */ @@ -26,7 +23,6 @@ const LG4: f32 = 0.24279078841; /* 0xf89e26.0p-26 */ #[inline] #[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)] -#[cfg_attr(test, libm_test)] pub fn logf(mut x: f32) -> f32 { let x1p25 = f32::from_bits(0x4c000000); // 0x1p25f === 2 ^ 25 diff --git a/src/math/modf.rs b/src/math/modf.rs index 7adf6ff01..bcab33a81 100644 --- a/src/math/modf.rs +++ b/src/math/modf.rs @@ -1,7 +1,3 @@ -#[cfg(test)] -use libm_test::libm_test; - -#[cfg_attr(test, libm_test)] pub fn modf(x: f64) -> (f64, f64) { let rv2: f64; let mut u = x.to_bits(); diff --git a/src/math/modff.rs b/src/math/modff.rs index a1f1f4f5d..56ece12e3 100644 --- a/src/math/modff.rs +++ b/src/math/modff.rs @@ -1,7 +1,3 @@ -#[cfg(test)] -use libm_test::libm_test; - -#[cfg_attr(test, libm_test)] pub fn modff(x: f32) -> (f32, f32) { let rv2: f32; let mut u: u32 = x.to_bits(); diff --git a/src/math/pow.rs b/src/math/pow.rs index 4de819db5..111d712ff 100644 --- a/src/math/pow.rs +++ b/src/math/pow.rs @@ -57,10 +57,7 @@ // compiler will convert from decimal to binary accurately enough // to produce the hexadecimal values shown. // - use super::{fabs, get_high_word, scalbn, sqrt, with_set_high_word, with_set_low_word}; -#[cfg(test)] -use libm_test::libm_test; const BP: [f64; 2] = [1.0, 1.5]; const DP_H: [f64; 2] = [0.0, 5.84962487220764160156e-01]; /* 0x3fe2b803_40000000 */ @@ -94,7 +91,6 @@ const IVLN2_L: f64 = 1.92596299112661746887e-08; /* 0x3e54ae0b_f85ddf44 =1/ln2 t #[inline] #[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)] -#[cfg_attr(test, libm_test)] pub fn pow(x: f64, y: f64) -> f64 { let t1: f64; let t2: f64; @@ -483,7 +479,6 @@ mod tests { .for_each(|s| s.iter().for_each(|val| pow_test(base, *val, expected))); } - #[allow(bare_trait_objects)] fn test_sets(sets: &[&[f64]], computed: &Fn(f64) -> f64, expected: &Fn(f64) -> f64) { sets.iter().for_each(|s| { s.iter().for_each(|val| { diff --git a/src/math/powf.rs b/src/math/powf.rs index 45c5d65a3..015bade86 100644 --- a/src/math/powf.rs +++ b/src/math/powf.rs @@ -14,8 +14,6 @@ */ use super::{fabsf, scalbnf, sqrtf}; -#[cfg(test)] -use libm_test::libm_test; const BP: [f32; 2] = [1.0, 1.5]; const DP_H: [f32; 2] = [0.0, 5.84960938e-01]; /* 0x3f15c000 */ @@ -47,7 +45,6 @@ const IVLN2_L: f32 = 7.0526075433e-06; #[inline] #[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)] -#[cfg_attr(test, libm_test)] pub fn powf(x: f32, y: f32) -> f32 { let mut z: f32; let mut ax: f32; diff --git a/src/math/remquo.rs b/src/math/remquo.rs index 2ac566607..1c2ba8918 100644 --- a/src/math/remquo.rs +++ b/src/math/remquo.rs @@ -1,7 +1,3 @@ -#[cfg(test)] -use libm_test::libm_test; - -#[cfg_attr(test, libm_test)] pub fn remquo(mut x: f64, mut y: f64) -> (f64, i32) { let ux: u64 = x.to_bits(); let mut uy: u64 = y.to_bits(); diff --git a/src/math/remquof.rs b/src/math/remquof.rs index 6254fcabd..871d0c7d6 100644 --- a/src/math/remquof.rs +++ b/src/math/remquof.rs @@ -1,7 +1,3 @@ -#[cfg(test)] -use libm_test::libm_test; - -#[cfg_attr(test, libm_test)] pub fn remquof(mut x: f32, mut y: f32) -> (f32, i32) { let ux: u32 = x.to_bits(); let mut uy: u32 = y.to_bits(); diff --git a/src/math/round.rs b/src/math/round.rs index a95074142..67590d2c1 100644 --- a/src/math/round.rs +++ b/src/math/round.rs @@ -1,12 +1,9 @@ use core::f64; -#[cfg(test)] -use libm_test::libm_test; const TOINT: f64 = 1.0 / f64::EPSILON; #[inline] #[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)] -#[cfg_attr(test, libm_test)] pub fn round(mut x: f64) -> f64 { let i = x.to_bits(); let e: u64 = i >> 52 & 0x7ff; diff --git a/src/math/roundf.rs b/src/math/roundf.rs index dbdc2df41..85114be4b 100644 --- a/src/math/roundf.rs +++ b/src/math/roundf.rs @@ -1,12 +1,9 @@ use core::f32; -#[cfg(test)] -use libm_test::libm_test; const TOINT: f32 = 1.0 / f32::EPSILON; #[inline] #[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)] -#[cfg_attr(test, libm_test)] pub fn roundf(mut x: f32) -> f32 { let i = x.to_bits(); let e: u32 = i >> 23 & 0xff; diff --git a/src/math/scalbn.rs b/src/math/scalbn.rs index 05672c755..d8c8409ac 100644 --- a/src/math/scalbn.rs +++ b/src/math/scalbn.rs @@ -1,9 +1,5 @@ -#[cfg(test)] -use libm_test::libm_test; - #[inline] #[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)] -#[cfg_attr(test, libm_test)] pub fn scalbn(x: f64, mut n: i32) -> f64 { let x1p1023 = f64::from_bits(0x7fe0000000000000); // 0x1p1023 === 2 ^ 1023 let x1p53 = f64::from_bits(0x4340000000000000); // 0x1p53 === 2 ^ 53 diff --git a/src/math/scalbnf.rs b/src/math/scalbnf.rs index 59a62a4c6..4e9771175 100644 --- a/src/math/scalbnf.rs +++ b/src/math/scalbnf.rs @@ -1,9 +1,5 @@ -#[cfg(test)] -use libm_test::libm_test; - #[inline] #[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)] -#[cfg_attr(test, libm_test)] pub fn scalbnf(mut x: f32, mut n: i32) -> f32 { let x1p127 = f32::from_bits(0x7f000000); // 0x1p127f === 2 ^ 127 let x1p_126 = f32::from_bits(0x800000); // 0x1p-126f === 2 ^ -126 diff --git a/src/math/sin.rs b/src/math/sin.rs index e30ca94f0..51aed88a8 100644 --- a/src/math/sin.rs +++ b/src/math/sin.rs @@ -10,8 +10,6 @@ // ==================================================== use super::{k_cos, k_sin, rem_pio2}; -#[cfg(test)] -use libm_test::libm_test; // sin(x) // Return sine function of x. @@ -44,7 +42,6 @@ use libm_test::libm_test; // TRIG(x) returns trig(x) nearly rounded #[inline] #[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)] -#[cfg_attr(test, libm_test)] pub fn sin(x: f64) -> f64 { let x1p120 = f64::from_bits(0x4770000000000000); // 0x1p120f === 2 ^ 120 diff --git a/src/math/sincos.rs b/src/math/sincos.rs index fe9062a0c..750908df4 100644 --- a/src/math/sincos.rs +++ b/src/math/sincos.rs @@ -11,10 +11,7 @@ */ use super::{get_high_word, k_cos, k_sin, rem_pio2}; -#[cfg(test)] -use libm_test::libm_test; -#[cfg_attr(test, libm_test)] pub fn sincos(x: f64) -> (f64, f64) { let s: f64; let c: f64; diff --git a/src/math/sincosf.rs b/src/math/sincosf.rs index ff8559e79..bb9a00392 100644 --- a/src/math/sincosf.rs +++ b/src/math/sincosf.rs @@ -15,8 +15,6 @@ */ use super::{k_cosf, k_sinf, rem_pio2f}; -#[cfg(test)] -use libm_test::libm_test; /* Small multiples of pi/2 rounded to double precision. */ const PI_2: f32 = 0.5 * 3.1415926535897931160E+00; @@ -25,7 +23,6 @@ const S2PIO2: f32 = 2.0 * PI_2; /* 0x400921FB, 0x54442D18 */ const S3PIO2: f32 = 3.0 * PI_2; /* 0x4012D97C, 0x7F3321D2 */ const S4PIO2: f32 = 4.0 * PI_2; /* 0x401921FB, 0x54442D18 */ -#[cfg_attr(test, libm_test)] pub fn sincosf(x: f32) -> (f32, f32) { let s: f32; let c: f32; diff --git a/src/math/sinf.rs b/src/math/sinf.rs index 569da0eb3..0c31099ed 100644 --- a/src/math/sinf.rs +++ b/src/math/sinf.rs @@ -15,8 +15,6 @@ */ use super::{k_cosf, k_sinf, rem_pio2f}; -#[cfg(test)] -use libm_test::libm_test; use core::f64::consts::FRAC_PI_2; @@ -28,7 +26,6 @@ const S4_PIO2: f64 = 4. * FRAC_PI_2; /* 0x401921FB, 0x54442D18 */ #[inline] #[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)] -#[cfg_attr(test, libm_test)] pub fn sinf(x: f32) -> f32 { let x64 = x as f64; diff --git a/src/math/sinh.rs b/src/math/sinh.rs index bd0735b04..d36de66c1 100644 --- a/src/math/sinh.rs +++ b/src/math/sinh.rs @@ -1,6 +1,4 @@ use super::{expm1, expo2}; -#[cfg(test)] -use libm_test::libm_test; // sinh(x) = (exp(x) - 1/exp(x))/2 // = (exp(x)-1 + (exp(x)-1)/exp(x))/2 @@ -8,7 +6,6 @@ use libm_test::libm_test; // #[inline] #[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)] -#[cfg_attr(test, libm_test)] pub fn sinh(x: f64) -> f64 { // union {double f; uint64_t i;} u = {.f = x}; // uint32_t w; diff --git a/src/math/sinhf.rs b/src/math/sinhf.rs index 7a301c107..fd0b2bfc8 100644 --- a/src/math/sinhf.rs +++ b/src/math/sinhf.rs @@ -1,11 +1,8 @@ use super::expm1f; use super::k_expo2f; -#[cfg(test)] -use libm_test::libm_test; #[inline] #[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)] -#[cfg_attr(test, libm_test)] pub fn sinhf(x: f32) -> f32 { let mut h = 0.5f32; let mut ix = x.to_bits(); diff --git a/src/math/sqrt.rs b/src/math/sqrt.rs index fd16f4c20..14404d4eb 100644 --- a/src/math/sqrt.rs +++ b/src/math/sqrt.rs @@ -78,14 +78,11 @@ use core::f64; use core::num::Wrapping; -#[cfg(test)] -use libm_test::libm_test; const TINY: f64 = 1.0e-300; #[inline] #[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)] -#[cfg_attr(test, libm_test)] pub fn sqrt(x: f64) -> f64 { // On wasm32 we know that LLVM's intrinsic will compile to an optimized // `f64.sqrt` native instruction, so we can leverage this for both code size diff --git a/src/math/sqrtf.rs b/src/math/sqrtf.rs index f42d0a4f8..b9365c617 100644 --- a/src/math/sqrtf.rs +++ b/src/math/sqrtf.rs @@ -13,14 +13,10 @@ * ==================================================== */ -#[cfg(test)] -use libm_test::libm_test; - const TINY: f32 = 1.0e-30; #[inline] #[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)] -#[cfg_attr(test, libm_test)] pub fn sqrtf(x: f32) -> f32 { // On wasm32 we know that LLVM's intrinsic will compile to an optimized // `f32.sqrt` native instruction, so we can leverage this for both code size diff --git a/src/math/tan.rs b/src/math/tan.rs index ed2fc9017..e5c94cbb1 100644 --- a/src/math/tan.rs +++ b/src/math/tan.rs @@ -10,8 +10,6 @@ // ==================================================== use super::{k_tan, rem_pio2}; -#[cfg(test)] -use libm_test::libm_test; // tan(x) // Return tangent function of x. @@ -43,7 +41,6 @@ use libm_test::libm_test; // TRIG(x) returns trig(x) nearly rounded #[inline] #[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)] -#[cfg_attr(test, libm_test)] pub fn tan(x: f64) -> f64 { let x1p120 = f32::from_bits(0x7b800000); // 0x1p120f === 2 ^ 120 diff --git a/src/math/tanf.rs b/src/math/tanf.rs index 672128d51..c286cdeb4 100644 --- a/src/math/tanf.rs +++ b/src/math/tanf.rs @@ -15,8 +15,6 @@ */ use super::{k_tanf, rem_pio2f}; -#[cfg(test)] -use libm_test::libm_test; use core::f64::consts::FRAC_PI_2; @@ -28,7 +26,6 @@ const T4_PIO2: f64 = 4. * FRAC_PI_2; /* 0x401921FB, 0x54442D18 */ #[inline] #[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)] -#[cfg_attr(test, libm_test)] pub fn tanf(x: f32) -> f32 { let x64 = x as f64; diff --git a/src/math/tanh.rs b/src/math/tanh.rs index 6fe19d901..75d695cf7 100644 --- a/src/math/tanh.rs +++ b/src/math/tanh.rs @@ -1,6 +1,4 @@ use super::expm1; -#[cfg(test)] -use libm_test::libm_test; /* tanh(x) = (exp(x) - exp(-x))/(exp(x) + exp(-x)) * = (exp(2*x) - 1)/(exp(2*x) - 1 + 2) @@ -8,7 +6,6 @@ use libm_test::libm_test; */ #[inline] #[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)] -#[cfg_attr(test, libm_test)] pub fn tanh(mut x: f64) -> f64 { let mut uf: f64 = x; let mut ui: u64 = f64::to_bits(uf); diff --git a/src/math/tanhf.rs b/src/math/tanhf.rs index b8d2e8337..ac4657b5a 100644 --- a/src/math/tanhf.rs +++ b/src/math/tanhf.rs @@ -1,10 +1,7 @@ use super::expm1f; -#[cfg(test)] -use libm_test::libm_test; #[inline] #[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)] -#[cfg_attr(test, libm_test)] pub fn tanhf(mut x: f32) -> f32 { /* x = |x| */ let mut ix = x.to_bits(); diff --git a/src/math/tgamma.rs b/src/math/tgamma.rs index c58097942..f8ccf669a 100644 --- a/src/math/tgamma.rs +++ b/src/math/tgamma.rs @@ -24,8 +24,6 @@ most ideas and constants are from boost and python */ extern crate core; use super::{exp, floor, k_cos, k_sin, pow}; -#[cfg(test)] -use libm_test::libm_test; const PI: f64 = 3.141592653589793238462643383279502884; @@ -132,7 +130,6 @@ fn s(x: f64) -> f64 { return num / den; } -#[cfg_attr(test, libm_test)] pub fn tgamma(mut x: f64) -> f64 { let u: u64 = x.to_bits(); let absx: f64; diff --git a/src/math/tgammaf.rs b/src/math/tgammaf.rs index f52f687ca..a8f161f0c 100644 --- a/src/math/tgammaf.rs +++ b/src/math/tgammaf.rs @@ -1,8 +1,5 @@ use super::tgamma; -#[cfg(test)] -use libm_test::libm_test; -#[cfg_attr(test, libm_test)] pub fn tgammaf(x: f32) -> f32 { tgamma(x as f64) as f32 } diff --git a/src/math/trunc.rs b/src/math/trunc.rs index 75f342798..1ee46fc7d 100644 --- a/src/math/trunc.rs +++ b/src/math/trunc.rs @@ -1,10 +1,7 @@ use core::f64; -#[cfg(test)] -use libm_test::libm_test; #[inline] #[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)] -#[cfg_attr(test, libm_test)] pub fn trunc(x: f64) -> f64 { // On wasm32 we know that LLVM's intrinsic will compile to an optimized // `f64.trunc` native instruction, so we can leverage this for both code size diff --git a/src/math/truncf.rs b/src/math/truncf.rs index 82305d5b7..f93383269 100644 --- a/src/math/truncf.rs +++ b/src/math/truncf.rs @@ -1,10 +1,7 @@ use core::f32; -#[cfg(test)] -use libm_test::libm_test; #[inline] #[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)] -#[cfg_attr(test, libm_test)] pub fn truncf(x: f32) -> f32 { // On wasm32 we know that LLVM's intrinsic will compile to an optimized // `f32.trunc` native instruction, so we can leverage this for both code size