Revive Float+Real in no_std with libm
This commit is contained in:
parent
d394467906
commit
fec6c3610c
|
@ -17,6 +17,7 @@ exclude = ["/ci/*", "/.travis.yml", "/bors.toml"]
|
||||||
features = ["std"]
|
features = ["std"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
libm = { version = "~0.1.2", optional = true }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["std"]
|
default = ["std"]
|
||||||
|
|
80
src/float.rs
80
src/float.rs
|
@ -7,6 +7,9 @@ use core::f64;
|
||||||
|
|
||||||
use {Num, NumCast, ToPrimitive};
|
use {Num, NumCast, ToPrimitive};
|
||||||
|
|
||||||
|
#[cfg(feature = "libm")]
|
||||||
|
use libm::{F32Ext, F64Ext};
|
||||||
|
|
||||||
/// Generic trait for floating point numbers that works with `no_std`.
|
/// Generic trait for floating point numbers that works with `no_std`.
|
||||||
///
|
///
|
||||||
/// This trait implements a subset of the `Float` trait.
|
/// This trait implements a subset of the `Float` trait.
|
||||||
|
@ -897,8 +900,8 @@ impl FloatCore for f64 {
|
||||||
|
|
||||||
/// Generic trait for floating point numbers
|
/// Generic trait for floating point numbers
|
||||||
///
|
///
|
||||||
/// This trait is only available with the `std` feature.
|
/// This trait is only available with the `std` feature, or with the `libm` feature otherwise.
|
||||||
#[cfg(feature = "std")]
|
#[cfg(any(feature = "std", feature = "libm"))]
|
||||||
pub trait Float: Num + Copy + NumCast + PartialOrd + Neg<Output = Self> {
|
pub trait Float: Num + Copy + NumCast + PartialOrd + Neg<Output = Self> {
|
||||||
/// Returns the `NaN` value.
|
/// Returns the `NaN` value.
|
||||||
///
|
///
|
||||||
|
@ -1805,9 +1808,9 @@ pub trait Float: Num + Copy + NumCast + PartialOrd + Neg<Output = Self> {
|
||||||
fn integer_decode(self) -> (u64, i16, i8);
|
fn integer_decode(self) -> (u64, i16, i8);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(any(feature = "std", feature = "libm"))]
|
||||||
macro_rules! float_impl {
|
macro_rules! float_impl {
|
||||||
($T:ident $decode:ident) => {
|
($T:ident $decode:ident $LibmImpl:ident) => {
|
||||||
impl Float for $T {
|
impl Float for $T {
|
||||||
constant! {
|
constant! {
|
||||||
nan() -> $T::NAN;
|
nan() -> $T::NAN;
|
||||||
|
@ -1820,17 +1823,26 @@ macro_rules! float_impl {
|
||||||
max_value() -> $T::MAX;
|
max_value() -> $T::MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "std")]
|
||||||
#[inline]
|
#[inline]
|
||||||
#[allow(deprecated)]
|
#[allow(deprecated)]
|
||||||
fn abs_sub(self, other: Self) -> Self {
|
fn abs_sub(self, other: Self) -> Self {
|
||||||
<$T>::abs_sub(self, other)
|
<$T>::abs_sub(self, other)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(all(not(feature = "std"), feature = "libm"))]
|
||||||
|
#[inline]
|
||||||
|
#[allow(deprecated)]
|
||||||
|
fn abs_sub(self, other: Self) -> Self {
|
||||||
|
<$T as $LibmImpl>::fdim(self, other)
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn integer_decode(self) -> (u64, i16, i8) {
|
fn integer_decode(self) -> (u64, i16, i8) {
|
||||||
$decode(self)
|
$decode(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "std")]
|
||||||
forward! {
|
forward! {
|
||||||
Self::is_nan(self) -> bool;
|
Self::is_nan(self) -> bool;
|
||||||
Self::is_infinite(self) -> bool;
|
Self::is_infinite(self) -> bool;
|
||||||
|
@ -1880,6 +1892,56 @@ macro_rules! float_impl {
|
||||||
Self::acosh(self) -> Self;
|
Self::acosh(self) -> Self;
|
||||||
Self::atanh(self) -> Self;
|
Self::atanh(self) -> Self;
|
||||||
}
|
}
|
||||||
|
#[cfg(all(not(feature = "std"), feature = "libm"))]
|
||||||
|
forward! {
|
||||||
|
FloatCore::is_nan(self) -> bool;
|
||||||
|
FloatCore::is_infinite(self) -> bool;
|
||||||
|
FloatCore::is_finite(self) -> bool;
|
||||||
|
FloatCore::is_normal(self) -> bool;
|
||||||
|
FloatCore::classify(self) -> FpCategory;
|
||||||
|
$LibmImpl::floor(self) -> Self;
|
||||||
|
$LibmImpl::ceil(self) -> Self;
|
||||||
|
$LibmImpl::round(self) -> Self;
|
||||||
|
$LibmImpl::trunc(self) -> Self;
|
||||||
|
$LibmImpl::fract(self) -> Self;
|
||||||
|
$LibmImpl::abs(self) -> Self;
|
||||||
|
FloatCore::signum(self) -> Self;
|
||||||
|
FloatCore::is_sign_positive(self) -> bool;
|
||||||
|
FloatCore::is_sign_negative(self) -> bool;
|
||||||
|
$LibmImpl::mul_add(self, a: Self, b: Self) -> Self;
|
||||||
|
FloatCore::recip(self) -> Self;
|
||||||
|
FloatCore::powi(self, n: i32) -> Self;
|
||||||
|
$LibmImpl::powf(self, n: Self) -> Self;
|
||||||
|
$LibmImpl::sqrt(self) -> Self;
|
||||||
|
$LibmImpl::exp(self) -> Self;
|
||||||
|
$LibmImpl::exp2(self) -> Self;
|
||||||
|
$LibmImpl::ln(self) -> Self;
|
||||||
|
$LibmImpl::log(self, base: Self) -> Self;
|
||||||
|
$LibmImpl::log2(self) -> Self;
|
||||||
|
$LibmImpl::log10(self) -> Self;
|
||||||
|
FloatCore::to_degrees(self) -> Self;
|
||||||
|
FloatCore::to_radians(self) -> Self;
|
||||||
|
FloatCore::max(self, other: Self) -> Self;
|
||||||
|
FloatCore::min(self, other: Self) -> Self;
|
||||||
|
$LibmImpl::cbrt(self) -> Self;
|
||||||
|
$LibmImpl::hypot(self, other: Self) -> Self;
|
||||||
|
$LibmImpl::sin(self) -> Self;
|
||||||
|
$LibmImpl::cos(self) -> Self;
|
||||||
|
$LibmImpl::tan(self) -> Self;
|
||||||
|
$LibmImpl::asin(self) -> Self;
|
||||||
|
$LibmImpl::acos(self) -> Self;
|
||||||
|
$LibmImpl::atan(self) -> Self;
|
||||||
|
$LibmImpl::atan2(self, other: Self) -> Self;
|
||||||
|
$LibmImpl::sin_cos(self) -> (Self, Self);
|
||||||
|
$LibmImpl::exp_m1(self) -> Self;
|
||||||
|
$LibmImpl::ln_1p(self) -> Self;
|
||||||
|
$LibmImpl::sinh(self) -> Self;
|
||||||
|
$LibmImpl::cosh(self) -> Self;
|
||||||
|
$LibmImpl::tanh(self) -> Self;
|
||||||
|
$LibmImpl::asinh(self) -> Self;
|
||||||
|
$LibmImpl::acosh(self) -> Self;
|
||||||
|
$LibmImpl::atanh(self) -> Self;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -1916,10 +1978,10 @@ fn integer_decode_f64(f: f64) -> (u64, i16, i8) {
|
||||||
(mantissa, exponent, sign)
|
(mantissa, exponent, sign)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(any(feature = "std", feature = "libm"))]
|
||||||
float_impl!(f32 integer_decode_f32);
|
float_impl!(f32 integer_decode_f32 F32Ext);
|
||||||
#[cfg(feature = "std")]
|
#[cfg(any(feature = "std", feature = "libm"))]
|
||||||
float_impl!(f64 integer_decode_f64);
|
float_impl!(f64 integer_decode_f64 F64Ext);
|
||||||
|
|
||||||
macro_rules! float_const_impl {
|
macro_rules! float_const_impl {
|
||||||
($(#[$doc:meta] $constant:ident,)+) => (
|
($(#[$doc:meta] $constant:ident,)+) => (
|
||||||
|
@ -2002,7 +2064,7 @@ mod tests {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(any(feature = "std", feature = "libm"))]
|
||||||
#[test]
|
#[test]
|
||||||
fn convert_deg_rad_std() {
|
fn convert_deg_rad_std() {
|
||||||
for &(deg, rad) in &DEG_RAD_PAIRS {
|
for &(deg, rad) in &DEG_RAD_PAIRS {
|
||||||
|
|
|
@ -20,13 +20,16 @@
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
extern crate std;
|
extern crate std;
|
||||||
|
|
||||||
|
#[cfg(feature = "libm")]
|
||||||
|
extern crate libm;
|
||||||
|
|
||||||
use core::fmt;
|
use core::fmt;
|
||||||
use core::num::Wrapping;
|
use core::num::Wrapping;
|
||||||
use core::ops::{Add, Div, Mul, Rem, Sub};
|
use core::ops::{Add, Div, Mul, Rem, Sub};
|
||||||
use core::ops::{AddAssign, DivAssign, MulAssign, RemAssign, SubAssign};
|
use core::ops::{AddAssign, DivAssign, MulAssign, RemAssign, SubAssign};
|
||||||
|
|
||||||
pub use bounds::Bounded;
|
pub use bounds::Bounded;
|
||||||
#[cfg(feature = "std")]
|
#[cfg(any(feature = "std", feature = "libm"))]
|
||||||
pub use float::Float;
|
pub use float::Float;
|
||||||
pub use float::FloatConst;
|
pub use float::FloatConst;
|
||||||
// pub use real::{FloatCore, Real}; // NOTE: Don't do this, it breaks `use num_traits::*;`.
|
// pub use real::{FloatCore, Real}; // NOTE: Don't do this, it breaks `use num_traits::*;`.
|
||||||
|
@ -53,7 +56,7 @@ pub mod identities;
|
||||||
pub mod int;
|
pub mod int;
|
||||||
pub mod ops;
|
pub mod ops;
|
||||||
pub mod pow;
|
pub mod pow;
|
||||||
#[cfg(feature = "std")]
|
#[cfg(any(feature = "std", feature = "libm"))]
|
||||||
pub mod real;
|
pub mod real;
|
||||||
pub mod sign;
|
pub mod sign;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use std::ops::Neg;
|
use core::ops::Neg;
|
||||||
|
|
||||||
use {Float, Num, NumCast};
|
use {Float, Num, NumCast};
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ use {Float, Num, NumCast};
|
||||||
/// See [this Wikipedia article](https://en.wikipedia.org/wiki/Real_data_type)
|
/// See [this Wikipedia article](https://en.wikipedia.org/wiki/Real_data_type)
|
||||||
/// for a list of data types that could meaningfully implement this trait.
|
/// for a list of data types that could meaningfully implement this trait.
|
||||||
///
|
///
|
||||||
/// This trait is only available with the `std` feature.
|
/// This trait is only available with the `std` feature, or with the `libm` feature otherwise.
|
||||||
pub trait Real: Num + Copy + NumCast + PartialOrd + Neg<Output = Self> {
|
pub trait Real: Num + Copy + NumCast + PartialOrd + Neg<Output = Self> {
|
||||||
/// Returns the smallest finite value that this type can represent.
|
/// Returns the smallest finite value that this type can represent.
|
||||||
///
|
///
|
||||||
|
|
Loading…
Reference in New Issue