|
@@ -10,22 +10,30 @@
|
|
|
|
|
|
//! Numeric traits for generic mathematics
|
|
|
|
|
|
-#![doc(html_root_url = "https://docs.rs/num-traits/0.1")]
|
|
|
+#![doc(html_root_url = "https://docs.rs/num-traits/0.2")]
|
|
|
|
|
|
-use std::ops::{Add, Sub, Mul, Div, Rem};
|
|
|
-use std::ops::{AddAssign, SubAssign, MulAssign, DivAssign, RemAssign};
|
|
|
-use std::num::Wrapping;
|
|
|
-use std::fmt;
|
|
|
+#![deny(unconditional_recursion)]
|
|
|
+
|
|
|
+#![cfg_attr(not(feature = "std"), no_std)]
|
|
|
+#[cfg(feature = "std")]
|
|
|
+extern crate core;
|
|
|
+
|
|
|
+use core::ops::{Add, Sub, Mul, Div, Rem};
|
|
|
+use core::ops::{AddAssign, SubAssign, MulAssign, DivAssign, RemAssign};
|
|
|
+use core::num::Wrapping;
|
|
|
+use core::fmt;
|
|
|
|
|
|
pub use bounds::Bounded;
|
|
|
-pub use float::{Float, FloatConst};
|
|
|
+#[cfg(feature = "std")]
|
|
|
+pub use float::Float;
|
|
|
+pub use float::FloatConst;
|
|
|
// pub use real::Real; // NOTE: Don't do this, it breaks `use num_traits::*;`.
|
|
|
pub use identities::{Zero, One, zero, one};
|
|
|
-pub use ops::checked::*;
|
|
|
-pub use ops::wrapping::*;
|
|
|
+pub use ops::checked::{CheckedAdd, CheckedSub, CheckedMul, CheckedDiv, CheckedShl, CheckedShr};
|
|
|
+pub use ops::wrapping::{WrappingAdd, WrappingMul, WrappingSub};
|
|
|
pub use ops::saturating::Saturating;
|
|
|
pub use sign::{Signed, Unsigned, abs, abs_sub, signum};
|
|
|
-pub use cast::*;
|
|
|
+pub use cast::{AsPrimitive, FromPrimitive, ToPrimitive, NumCast, cast};
|
|
|
pub use int::PrimInt;
|
|
|
pub use pow::{pow, checked_pow};
|
|
|
|
|
@@ -34,6 +42,7 @@ pub mod sign;
|
|
|
pub mod ops;
|
|
|
pub mod bounds;
|
|
|
pub mod float;
|
|
|
+#[cfg(feature = "std")]
|
|
|
pub mod real;
|
|
|
pub mod cast;
|
|
|
pub mod int;
|
|
@@ -130,10 +139,10 @@ impl<T> NumAssignRef for T where T: NumAssign + for<'r> NumAssignOps<&'r T> {}
|
|
|
macro_rules! int_trait_impl {
|
|
|
($name:ident for $($t:ty)*) => ($(
|
|
|
impl $name for $t {
|
|
|
- type FromStrRadixErr = ::std::num::ParseIntError;
|
|
|
+ type FromStrRadixErr = ::core::num::ParseIntError;
|
|
|
#[inline]
|
|
|
fn from_str_radix(s: &str, radix: u32)
|
|
|
- -> Result<Self, ::std::num::ParseIntError>
|
|
|
+ -> Result<Self, ::core::num::ParseIntError>
|
|
|
{
|
|
|
<$t>::from_str_radix(s, radix)
|
|
|
}
|
|
@@ -159,7 +168,7 @@ pub enum FloatErrorKind {
|
|
|
Empty,
|
|
|
Invalid,
|
|
|
}
|
|
|
-// FIXME: std::num::ParseFloatError is stable in 1.0, but opaque to us,
|
|
|
+// FIXME: core::num::ParseFloatError is stable in 1.0, but opaque to us,
|
|
|
// so there's not really any way for us to reuse it.
|
|
|
#[derive(Debug)]
|
|
|
pub struct ParseFloatError {
|
|
@@ -181,7 +190,7 @@ impl fmt::Display for ParseFloatError {
|
|
|
// with this implementation ourselves until we want to make a breaking change.
|
|
|
// (would have to drop it from `Num` though)
|
|
|
macro_rules! float_trait_impl {
|
|
|
- ($name:ident for $($t:ty)*) => ($(
|
|
|
+ ($name:ident for $($t:ident)*) => ($(
|
|
|
impl $name for $t {
|
|
|
type FromStrRadixErr = ParseFloatError;
|
|
|
|
|
@@ -193,9 +202,9 @@ macro_rules! float_trait_impl {
|
|
|
|
|
|
// Special values
|
|
|
match src {
|
|
|
- "inf" => return Ok(Float::infinity()),
|
|
|
- "-inf" => return Ok(Float::neg_infinity()),
|
|
|
- "NaN" => return Ok(Float::nan()),
|
|
|
+ "inf" => return Ok(core::$t::INFINITY),
|
|
|
+ "-inf" => return Ok(core::$t::NEG_INFINITY),
|
|
|
+ "NaN" => return Ok(core::$t::NAN),
|
|
|
_ => {},
|
|
|
}
|
|
|
|
|
@@ -236,15 +245,15 @@ macro_rules! float_trait_impl {
|
|
|
// if we've not seen any non-zero digits.
|
|
|
if prev_sig != 0.0 {
|
|
|
if is_positive && sig <= prev_sig
|
|
|
- { return Ok(Float::infinity()); }
|
|
|
+ { return Ok(core::$t::INFINITY); }
|
|
|
if !is_positive && sig >= prev_sig
|
|
|
- { return Ok(Float::neg_infinity()); }
|
|
|
+ { return Ok(core::$t::NEG_INFINITY); }
|
|
|
|
|
|
// Detect overflow by reversing the shift-and-add process
|
|
|
if is_positive && (prev_sig != (sig - digit as $t) / radix as $t)
|
|
|
- { return Ok(Float::infinity()); }
|
|
|
+ { return Ok(core::$t::INFINITY); }
|
|
|
if !is_positive && (prev_sig != (sig + digit as $t) / radix as $t)
|
|
|
- { return Ok(Float::neg_infinity()); }
|
|
|
+ { return Ok(core::$t::NEG_INFINITY); }
|
|
|
}
|
|
|
prev_sig = sig;
|
|
|
},
|
|
@@ -280,9 +289,9 @@ macro_rules! float_trait_impl {
|
|
|
};
|
|
|
// Detect overflow by comparing to last value
|
|
|
if is_positive && sig < prev_sig
|
|
|
- { return Ok(Float::infinity()); }
|
|
|
+ { return Ok(core::$t::INFINITY); }
|
|
|
if !is_positive && sig > prev_sig
|
|
|
- { return Ok(Float::neg_infinity()); }
|
|
|
+ { return Ok(core::$t::NEG_INFINITY); }
|
|
|
prev_sig = sig;
|
|
|
},
|
|
|
None => match c {
|
|
@@ -316,9 +325,15 @@ macro_rules! float_trait_impl {
|
|
|
None => return Err(PFE { kind: Invalid }),
|
|
|
};
|
|
|
|
|
|
+ #[cfg(feature = "std")]
|
|
|
+ fn pow(base: $t, exp: usize) -> $t {
|
|
|
+ Float::powi(base, exp as i32)
|
|
|
+ }
|
|
|
+ // otherwise uses the generic `pow` from the root
|
|
|
+
|
|
|
match (is_positive, exp) {
|
|
|
- (true, Ok(exp)) => base.powi(exp as i32),
|
|
|
- (false, Ok(exp)) => 1.0 / base.powi(exp as i32),
|
|
|
+ (true, Ok(exp)) => pow(base, exp),
|
|
|
+ (false, Ok(exp)) => 1.0 / pow(base, exp),
|
|
|
(_, Err(_)) => return Err(PFE { kind: Invalid }),
|
|
|
}
|
|
|
},
|