Merge #62
62: re-structure for compiler-builtins integration and add extension traits r=japaric a=japaric Co-authored-by: Jorge Aparicio <jorge@japaric.io>
This commit is contained in:
@@ -31,7 +31,8 @@ $ TARGET=armv7-unknown-linux-gnueabihf bash ci/script.sh
|
||||
|
||||
- Pick your favorite math function from the [issue tracker].
|
||||
- Look for the C implementation of the function in the [MUSL source code][src].
|
||||
- Copy paste the C code into a Rust file in the `src` directory and adjust `src/lib.rs` accordingly.
|
||||
- Copy paste the C code into a Rust file in the `src/math` directory and adjust `src/math/mod.rs`
|
||||
accordingly.
|
||||
- Run `cargo watch check` and fix the compiler errors.
|
||||
- Tweak the bottom of `test-generator/src/main.rs` to add your function to the test suite.
|
||||
- If you can, run the test suite locally. If you can't, no problem! Your PR will be tested
|
||||
|
||||
+690
-14
@@ -1,19 +1,23 @@
|
||||
//! Port of MUSL's libm to Rust
|
||||
//!
|
||||
//! # Usage
|
||||
//!
|
||||
//! You can use this crate in two ways:
|
||||
//!
|
||||
//! - By directly using its free functions, e.g. `libm::powf`.
|
||||
//!
|
||||
//! - By importing the `F32Ext` and / or `F64Ext` extension traits to add methods like `powf` to the
|
||||
//! `f32` and `f64` types. Then you'll be able to invoke math functions as methods, e.g. `x.sqrt()`.
|
||||
|
||||
#![deny(warnings)]
|
||||
#![no_std]
|
||||
|
||||
mod fabs;
|
||||
mod fabsf;
|
||||
mod fmodf;
|
||||
mod powf;
|
||||
mod scalbnf;
|
||||
mod sqrtf;
|
||||
mod math;
|
||||
|
||||
pub use fabs::fabs;
|
||||
pub use fabsf::fabsf;
|
||||
pub use fmodf::fmodf;
|
||||
pub use powf::powf;
|
||||
pub use scalbnf::scalbnf;
|
||||
pub use sqrtf::sqrtf;
|
||||
#[cfg(todo)]
|
||||
use core::{f32, f64};
|
||||
|
||||
pub use math::*;
|
||||
|
||||
/// Approximate equality with 1 ULP of tolerance
|
||||
#[doc(hidden)]
|
||||
@@ -26,6 +30,678 @@ pub fn _eq(a: u64, b: u64) -> bool {
|
||||
(a as i64).wrapping_sub(b as i64).abs() <= 1
|
||||
}
|
||||
|
||||
fn isnanf(x: f32) -> bool {
|
||||
x.to_bits() & 0x7fffffff > 0x7f800000
|
||||
/// Math support for `f32`
|
||||
///
|
||||
/// NOTE this meant to be a closed extension trait. The only stable way to use this trait is to
|
||||
/// import it to access its methods.
|
||||
pub trait F32Ext {
|
||||
#[cfg(todo)]
|
||||
fn floor(self) -> Self;
|
||||
|
||||
#[cfg(todo)]
|
||||
fn ceil(self) -> Self;
|
||||
|
||||
#[cfg(todo)]
|
||||
fn round(self) -> Self;
|
||||
|
||||
#[cfg(todo)]
|
||||
fn trunc(self) -> Self;
|
||||
|
||||
#[cfg(todo)]
|
||||
fn fract(self) -> Self;
|
||||
|
||||
fn abs(self) -> Self;
|
||||
|
||||
#[cfg(todo)]
|
||||
fn signum(self) -> Self;
|
||||
|
||||
#[cfg(todo)]
|
||||
fn mul_add(self, a: Self, b: Self) -> Self;
|
||||
|
||||
#[cfg(todo)]
|
||||
fn div_euc(self, rhs: Self) -> Self;
|
||||
|
||||
#[cfg(todo)]
|
||||
fn mod_euc(self, rhs: Self) -> Self;
|
||||
|
||||
// NOTE depends on unstable intrinsics::powif32
|
||||
// fn powi(self, n: i32) -> Self;
|
||||
|
||||
fn powf(self, n: Self) -> Self;
|
||||
|
||||
fn sqrt(self) -> Self;
|
||||
|
||||
#[cfg(todo)]
|
||||
fn exp(self) -> Self;
|
||||
|
||||
#[cfg(todo)]
|
||||
fn exp2(self) -> Self;
|
||||
|
||||
#[cfg(todo)]
|
||||
fn ln(self) -> Self;
|
||||
|
||||
#[cfg(todo)]
|
||||
fn log(self, base: Self) -> Self;
|
||||
|
||||
#[cfg(todo)]
|
||||
fn log2(self) -> Self;
|
||||
|
||||
#[cfg(todo)]
|
||||
fn log10(self) -> Self;
|
||||
|
||||
#[cfg(todo)]
|
||||
fn cbrt(self) -> Self;
|
||||
|
||||
#[cfg(todo)]
|
||||
fn hypot(self, other: Self) -> Self;
|
||||
|
||||
#[cfg(todo)]
|
||||
fn sin(self) -> Self;
|
||||
|
||||
#[cfg(todo)]
|
||||
fn cos(self) -> Self;
|
||||
|
||||
#[cfg(todo)]
|
||||
fn tan(self) -> Self;
|
||||
|
||||
#[cfg(todo)]
|
||||
fn asin(self) -> Self;
|
||||
|
||||
#[cfg(todo)]
|
||||
fn acos(self) -> Self;
|
||||
|
||||
#[cfg(todo)]
|
||||
fn atan(self) -> Self;
|
||||
|
||||
#[cfg(todo)]
|
||||
fn atan2(self, other: Self) -> Self;
|
||||
|
||||
#[cfg(todo)]
|
||||
#[inline]
|
||||
fn sin_cos(self) -> (Self, Self) {
|
||||
(self.sin(), self.cos())
|
||||
}
|
||||
|
||||
#[cfg(todo)]
|
||||
fn exp_m1(self) -> Self;
|
||||
|
||||
#[cfg(todo)]
|
||||
fn ln_1p(self) -> Self;
|
||||
|
||||
#[cfg(todo)]
|
||||
fn sinh(self) -> Self;
|
||||
|
||||
#[cfg(todo)]
|
||||
fn cosh(self) -> Self;
|
||||
|
||||
#[cfg(todo)]
|
||||
fn tanh(self) -> Self;
|
||||
|
||||
#[cfg(todo)]
|
||||
fn asinh(self) -> Self;
|
||||
|
||||
#[cfg(todo)]
|
||||
fn acosh(self) -> Self;
|
||||
|
||||
#[cfg(todo)]
|
||||
fn atanh(self) -> Self;
|
||||
}
|
||||
|
||||
impl F32Ext for f32 {
|
||||
#[cfg(todo)]
|
||||
#[inline]
|
||||
fn floor(self) -> Self {
|
||||
floorf(self)
|
||||
}
|
||||
|
||||
#[cfg(todo)]
|
||||
#[inline]
|
||||
fn ceil(self) -> Self {
|
||||
ceilf(self)
|
||||
}
|
||||
|
||||
#[cfg(todo)]
|
||||
#[inline]
|
||||
fn round(self) -> Self {
|
||||
roundf(self)
|
||||
}
|
||||
|
||||
#[cfg(todo)]
|
||||
#[inline]
|
||||
fn trunc(self) -> Self {
|
||||
truncf(self)
|
||||
}
|
||||
|
||||
#[cfg(todo)]
|
||||
#[inline]
|
||||
fn fract(self) -> Self {
|
||||
self - self.trunc()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn abs(self) -> Self {
|
||||
fabsf(self)
|
||||
}
|
||||
|
||||
#[cfg(todo)]
|
||||
#[inline]
|
||||
fn mul_add(self, a: Self, b: Self) -> Self {
|
||||
fmaf(self, a, b)
|
||||
}
|
||||
|
||||
#[cfg(todo)]
|
||||
#[inline]
|
||||
fn div_euc(self, rhs: Self) -> Self {
|
||||
let q = (self / rhs).trunc();
|
||||
if self % rhs < 0.0 {
|
||||
return if rhs > 0.0 { q - 1.0 } else { q + 1.0 };
|
||||
}
|
||||
q
|
||||
}
|
||||
|
||||
#[cfg(todo)]
|
||||
#[inline]
|
||||
fn mod_euc(self, rhs: f32) -> f32 {
|
||||
let r = self % rhs;
|
||||
if r < 0.0 {
|
||||
r + rhs.abs()
|
||||
} else {
|
||||
r
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn powf(self, n: Self) -> Self {
|
||||
powf(self, n)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn sqrt(self) -> Self {
|
||||
sqrtf(self)
|
||||
}
|
||||
|
||||
#[cfg(todo)]
|
||||
#[inline]
|
||||
fn exp(self) -> Self {
|
||||
expf(self)
|
||||
}
|
||||
|
||||
#[cfg(todo)]
|
||||
#[inline]
|
||||
fn exp2(self) -> Self {
|
||||
exp2f(self)
|
||||
}
|
||||
|
||||
#[cfg(todo)]
|
||||
#[inline]
|
||||
fn ln(self) -> Self {
|
||||
logf(self)
|
||||
}
|
||||
|
||||
#[cfg(todo)]
|
||||
#[inline]
|
||||
fn log(self, base: Self) -> Self {
|
||||
self.ln() / base.ln()
|
||||
}
|
||||
|
||||
#[cfg(todo)]
|
||||
#[inline]
|
||||
fn log2(self) -> Self {
|
||||
log2f(self)
|
||||
}
|
||||
|
||||
#[cfg(todo)]
|
||||
#[inline]
|
||||
fn log10(self) -> Self {
|
||||
log10f(self)
|
||||
}
|
||||
|
||||
#[cfg(todo)]
|
||||
#[inline]
|
||||
fn cbrt(self) -> Self {
|
||||
cbrtf(self)
|
||||
}
|
||||
|
||||
#[cfg(todo)]
|
||||
#[inline]
|
||||
fn hypot(self, other: Self) -> Self {
|
||||
hypotf(self, other)
|
||||
}
|
||||
|
||||
#[cfg(todo)]
|
||||
#[inline]
|
||||
fn sin(self) -> Self {
|
||||
sinf(self)
|
||||
}
|
||||
|
||||
#[cfg(todo)]
|
||||
#[inline]
|
||||
fn cos(self) -> Self {
|
||||
cosf(self)
|
||||
}
|
||||
|
||||
#[cfg(todo)]
|
||||
#[inline]
|
||||
fn tan(self) -> Self {
|
||||
tanf(self)
|
||||
}
|
||||
|
||||
#[cfg(todo)]
|
||||
#[inline]
|
||||
fn asin(self) -> Self {
|
||||
asinf(self)
|
||||
}
|
||||
|
||||
#[cfg(todo)]
|
||||
#[inline]
|
||||
fn acos(self) -> Self {
|
||||
acosf(self)
|
||||
}
|
||||
|
||||
#[cfg(todo)]
|
||||
#[inline]
|
||||
fn atan(self) -> Self {
|
||||
atanf(self)
|
||||
}
|
||||
|
||||
#[cfg(todo)]
|
||||
#[inline]
|
||||
fn atan2(self, other: Self) -> Self {
|
||||
atan2f(self, other)
|
||||
}
|
||||
|
||||
#[cfg(todo)]
|
||||
#[inline]
|
||||
fn exp_m1(self) -> Self {
|
||||
expm1f(self)
|
||||
}
|
||||
|
||||
#[cfg(todo)]
|
||||
#[inline]
|
||||
fn ln_1p(self) -> Self {
|
||||
log1pf(self)
|
||||
}
|
||||
|
||||
#[cfg(todo)]
|
||||
#[inline]
|
||||
fn sinh(self) -> Self {
|
||||
sinhf(self)
|
||||
}
|
||||
|
||||
#[cfg(todo)]
|
||||
#[inline]
|
||||
fn cosh(self) -> Self {
|
||||
coshf(self)
|
||||
}
|
||||
|
||||
#[cfg(todo)]
|
||||
#[inline]
|
||||
fn tanh(self) -> Self {
|
||||
tanhf(self)
|
||||
}
|
||||
|
||||
#[cfg(todo)]
|
||||
#[inline]
|
||||
fn asinh(self) -> Self {
|
||||
if self == f32::NEG_INFINITY {
|
||||
f32::NEG_INFINITY
|
||||
} else {
|
||||
(self + ((self * self) + 1.0).sqrt()).ln()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(todo)]
|
||||
#[inline]
|
||||
fn acosh(self) -> Self {
|
||||
match self {
|
||||
x if x < 1.0 => f32::NAN,
|
||||
x => (x + ((x * x) - 1.0).sqrt()).ln(),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(todo)]
|
||||
#[inline]
|
||||
fn atanh(self) -> Self {
|
||||
0.5 * ((2.0 * self) / (1.0 - self)).ln_1p()
|
||||
}
|
||||
}
|
||||
|
||||
/// Math support for `f32`
|
||||
///
|
||||
/// NOTE this meant to be a closed extension trait. The only stable way to use this trait is to
|
||||
/// import it to access its methods.
|
||||
pub trait F64Ext {
|
||||
#[cfg(todo)]
|
||||
fn floor(self) -> Self;
|
||||
|
||||
#[cfg(todo)]
|
||||
fn ceil(self) -> Self;
|
||||
|
||||
#[cfg(todo)]
|
||||
fn round(self) -> Self;
|
||||
|
||||
#[cfg(todo)]
|
||||
fn trunc(self) -> Self;
|
||||
|
||||
#[cfg(todo)]
|
||||
fn fract(self) -> Self;
|
||||
|
||||
fn abs(self) -> Self;
|
||||
|
||||
#[cfg(todo)]
|
||||
fn signum(self) -> Self;
|
||||
|
||||
#[cfg(todo)]
|
||||
fn mul_add(self, a: Self, b: Self) -> Self;
|
||||
|
||||
#[cfg(todo)]
|
||||
fn div_euc(self, rhs: Self) -> Self;
|
||||
|
||||
#[cfg(todo)]
|
||||
fn mod_euc(self, rhs: Self) -> Self;
|
||||
|
||||
// NOTE depends on unstable intrinsics::powif64
|
||||
// fn powi(self, n: i32) -> Self;
|
||||
|
||||
#[cfg(todo)]
|
||||
fn powf(self, n: Self) -> Self;
|
||||
|
||||
#[cfg(todo)]
|
||||
fn sqrt(self) -> Self;
|
||||
|
||||
#[cfg(todo)]
|
||||
fn exp(self) -> Self;
|
||||
|
||||
#[cfg(todo)]
|
||||
fn exp2(self) -> Self;
|
||||
|
||||
#[cfg(todo)]
|
||||
fn ln(self) -> Self;
|
||||
|
||||
#[cfg(todo)]
|
||||
fn log(self, base: Self) -> Self;
|
||||
|
||||
#[cfg(todo)]
|
||||
fn log2(self) -> Self;
|
||||
|
||||
#[cfg(todo)]
|
||||
fn log10(self) -> Self;
|
||||
|
||||
#[cfg(todo)]
|
||||
fn cbrt(self) -> Self;
|
||||
|
||||
#[cfg(todo)]
|
||||
fn hypot(self, other: Self) -> Self;
|
||||
|
||||
#[cfg(todo)]
|
||||
fn sin(self) -> Self;
|
||||
|
||||
#[cfg(todo)]
|
||||
fn cos(self) -> Self;
|
||||
|
||||
#[cfg(todo)]
|
||||
fn tan(self) -> Self;
|
||||
|
||||
#[cfg(todo)]
|
||||
fn asin(self) -> Self;
|
||||
|
||||
#[cfg(todo)]
|
||||
fn acos(self) -> Self;
|
||||
|
||||
#[cfg(todo)]
|
||||
fn atan(self) -> Self;
|
||||
|
||||
#[cfg(todo)]
|
||||
fn atan2(self, other: Self) -> Self;
|
||||
|
||||
#[cfg(todo)]
|
||||
#[inline]
|
||||
fn sin_cos(self) -> (Self, Self) {
|
||||
(self.sin(), self.cos())
|
||||
}
|
||||
|
||||
#[cfg(todo)]
|
||||
fn exp_m1(self) -> Self;
|
||||
|
||||
#[cfg(todo)]
|
||||
fn ln_1p(self) -> Self;
|
||||
|
||||
#[cfg(todo)]
|
||||
fn sinh(self) -> Self;
|
||||
|
||||
#[cfg(todo)]
|
||||
fn cosh(self) -> Self;
|
||||
|
||||
#[cfg(todo)]
|
||||
fn tanh(self) -> Self;
|
||||
|
||||
#[cfg(todo)]
|
||||
fn asinh(self) -> Self;
|
||||
|
||||
#[cfg(todo)]
|
||||
fn acosh(self) -> Self;
|
||||
|
||||
#[cfg(todo)]
|
||||
fn atanh(self) -> Self;
|
||||
}
|
||||
|
||||
impl F64Ext for f64 {
|
||||
#[cfg(todo)]
|
||||
#[inline]
|
||||
fn floor(self) -> Self {
|
||||
floor(self)
|
||||
}
|
||||
|
||||
#[cfg(todo)]
|
||||
#[inline]
|
||||
fn ceil(self) -> Self {
|
||||
ceil(self)
|
||||
}
|
||||
|
||||
#[cfg(todo)]
|
||||
#[inline]
|
||||
fn round(self) -> Self {
|
||||
round(self)
|
||||
}
|
||||
|
||||
#[cfg(todo)]
|
||||
#[inline]
|
||||
fn trunc(self) -> Self {
|
||||
trunc(self)
|
||||
}
|
||||
|
||||
#[cfg(todo)]
|
||||
#[inline]
|
||||
fn fract(self) -> Self {
|
||||
self - self.trunc()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn abs(self) -> Self {
|
||||
fabs(self)
|
||||
}
|
||||
|
||||
#[cfg(todo)]
|
||||
#[inline]
|
||||
fn mul_add(self, a: Self, b: Self) -> Self {
|
||||
fma(self, a, b)
|
||||
}
|
||||
|
||||
#[cfg(todo)]
|
||||
#[inline]
|
||||
fn div_euc(self, rhs: Self) -> Self {
|
||||
let q = (self / rhs).trunc();
|
||||
if self % rhs < 0.0 {
|
||||
return if rhs > 0.0 { q - 1.0 } else { q + 1.0 };
|
||||
}
|
||||
q
|
||||
}
|
||||
|
||||
#[cfg(todo)]
|
||||
#[inline]
|
||||
fn mod_euc(self, rhs: f32) -> f32 {
|
||||
let r = self % rhs;
|
||||
if r < 0.0 {
|
||||
r + rhs.abs()
|
||||
} else {
|
||||
r
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(todo)]
|
||||
#[inline]
|
||||
fn powf(self, n: Self) -> Self {
|
||||
pow(self, n)
|
||||
}
|
||||
|
||||
#[cfg(todo)]
|
||||
#[inline]
|
||||
fn sqrt(self) -> Self {
|
||||
sqrt(self)
|
||||
}
|
||||
|
||||
#[cfg(todo)]
|
||||
#[inline]
|
||||
fn exp(self) -> Self {
|
||||
exp(self)
|
||||
}
|
||||
|
||||
#[cfg(todo)]
|
||||
#[inline]
|
||||
fn exp2(self) -> Self {
|
||||
exp2(self)
|
||||
}
|
||||
|
||||
#[cfg(todo)]
|
||||
#[inline]
|
||||
fn ln(self) -> Self {
|
||||
log(self)
|
||||
}
|
||||
|
||||
#[cfg(todo)]
|
||||
#[inline]
|
||||
fn log(self, base: Self) -> Self {
|
||||
self.ln() / base.ln()
|
||||
}
|
||||
|
||||
#[cfg(todo)]
|
||||
#[inline]
|
||||
fn log2(self) -> Self {
|
||||
log2(self)
|
||||
}
|
||||
|
||||
#[cfg(todo)]
|
||||
#[inline]
|
||||
fn log10(self) -> Self {
|
||||
log10(self)
|
||||
}
|
||||
|
||||
#[cfg(todo)]
|
||||
#[inline]
|
||||
fn cbrt(self) -> Self {
|
||||
cbrt(self)
|
||||
}
|
||||
|
||||
#[cfg(todo)]
|
||||
#[inline]
|
||||
fn hypot(self, other: Self) -> Self {
|
||||
hypot(self, other)
|
||||
}
|
||||
|
||||
#[cfg(todo)]
|
||||
#[inline]
|
||||
fn sin(self) -> Self {
|
||||
sin(self)
|
||||
}
|
||||
|
||||
#[cfg(todo)]
|
||||
#[inline]
|
||||
fn cos(self) -> Self {
|
||||
cos(self)
|
||||
}
|
||||
|
||||
#[cfg(todo)]
|
||||
#[inline]
|
||||
fn tan(self) -> Self {
|
||||
tan(self)
|
||||
}
|
||||
|
||||
#[cfg(todo)]
|
||||
#[inline]
|
||||
fn asin(self) -> Self {
|
||||
asin(self)
|
||||
}
|
||||
|
||||
#[cfg(todo)]
|
||||
#[inline]
|
||||
fn acos(self) -> Self {
|
||||
acos(self)
|
||||
}
|
||||
|
||||
#[cfg(todo)]
|
||||
#[inline]
|
||||
fn atan(self) -> Self {
|
||||
atan(self)
|
||||
}
|
||||
|
||||
#[cfg(todo)]
|
||||
#[inline]
|
||||
fn atan2(self, other: Self) -> Self {
|
||||
atan2(self, other)
|
||||
}
|
||||
|
||||
#[cfg(todo)]
|
||||
#[inline]
|
||||
fn exp_m1(self) -> Self {
|
||||
expm1(self)
|
||||
}
|
||||
|
||||
#[cfg(todo)]
|
||||
#[inline]
|
||||
fn ln_1p(self) -> Self {
|
||||
log1p(self)
|
||||
}
|
||||
|
||||
#[cfg(todo)]
|
||||
#[inline]
|
||||
fn sinh(self) -> Self {
|
||||
sinh(self)
|
||||
}
|
||||
|
||||
#[cfg(todo)]
|
||||
#[inline]
|
||||
fn cosh(self) -> Self {
|
||||
cosh(self)
|
||||
}
|
||||
|
||||
#[cfg(todo)]
|
||||
#[inline]
|
||||
fn tanh(self) -> Self {
|
||||
tanh(self)
|
||||
}
|
||||
|
||||
#[cfg(todo)]
|
||||
#[inline]
|
||||
fn asinh(self) -> Self {
|
||||
if self == f64::NEG_INFINITY {
|
||||
f64::NEG_INFINITY
|
||||
} else {
|
||||
(self + ((self * self) + 1.0).sqrt()).ln()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(todo)]
|
||||
#[inline]
|
||||
fn acosh(self) -> Self {
|
||||
match self {
|
||||
x if x < 1.0 => f64::NAN,
|
||||
x => (x + ((x * x) - 1.0).sqrt()).ln(),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(todo)]
|
||||
#[inline]
|
||||
fn atanh(self) -> Self {
|
||||
0.5 * ((2.0 * self) / (1.0 - self)).ln_1p()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use core::u64;
|
||||
|
||||
#[inline]
|
||||
pub fn fabs(x: f64) -> f64 {
|
||||
f64::from_bits(x.to_bits() & (u64::MAX / 2))
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
#[inline]
|
||||
pub fn fabsf(x: f32) -> f32 {
|
||||
f32::from_bits(x.to_bits() & 0x7fffffff)
|
||||
}
|
||||
@@ -1,7 +1,8 @@
|
||||
use core::u32;
|
||||
|
||||
use isnanf;
|
||||
use super::isnanf;
|
||||
|
||||
#[inline]
|
||||
pub fn fmodf(x: f32, y: f32) -> f32 {
|
||||
let mut uxi = x.to_bits();
|
||||
let mut uyi = y.to_bits();
|
||||
@@ -0,0 +1,17 @@
|
||||
mod fabs;
|
||||
mod fabsf;
|
||||
mod fmodf;
|
||||
mod powf;
|
||||
mod scalbnf;
|
||||
mod sqrtf;
|
||||
|
||||
pub use self::fabs::fabs;
|
||||
pub use self::fabsf::fabsf;
|
||||
pub use self::fmodf::fmodf;
|
||||
pub use self::powf::powf;
|
||||
pub use self::scalbnf::scalbnf;
|
||||
pub use self::sqrtf::sqrtf;
|
||||
|
||||
fn isnanf(x: f32) -> bool {
|
||||
x.to_bits() & 0x7fffffff > 0x7f800000
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
use {scalbnf, sqrtf};
|
||||
use super::{fabsf, scalbnf, sqrtf};
|
||||
|
||||
const BP: [f32; 2] = [1.0, 1.5];
|
||||
const DP_H: [f32; 2] = [0.0, 5.84960938e-01]; /* 0x3f15c000 */
|
||||
@@ -28,6 +28,7 @@ const IVLN2: f32 = 1.4426950216e+00;
|
||||
const IVLN2_H: f32 = 1.4426879883e+00;
|
||||
const IVLN2_L: f32 = 7.0526075433e-06;
|
||||
|
||||
#[inline]
|
||||
pub fn powf(x: f32, y: f32) -> f32 {
|
||||
let mut z: f32;
|
||||
let mut ax: f32;
|
||||
@@ -127,7 +128,7 @@ pub fn powf(x: f32, y: f32) -> f32 {
|
||||
}
|
||||
}
|
||||
|
||||
ax = ::fabsf(x);
|
||||
ax = fabsf(x);
|
||||
/* special value of x */
|
||||
if ix == 0x7f800000 || ix == 0 || ix == 0x3f800000 {
|
||||
/* x is +-0,+-inf,+-1 */
|
||||
@@ -1,3 +1,4 @@
|
||||
#[inline]
|
||||
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
|
||||
@@ -1,5 +1,6 @@
|
||||
const TINY: f32 = 1.0e-30;
|
||||
|
||||
#[inline]
|
||||
pub fn sqrtf(x: f32) -> f32 {
|
||||
let mut z: f32;
|
||||
let sign: i32 = 0x80000000u32 as i32;
|
||||
Reference in New Issue
Block a user