lib.rs 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512
  1. // Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
  2. // file at the top-level directory of this distribution and at
  3. // http://rust-lang.org/COPYRIGHT.
  4. //
  5. // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
  6. // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
  7. // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
  8. // option. This file may not be copied, modified, or distributed
  9. // except according to those terms.
  10. //! Numeric traits for generic mathematics
  11. //!
  12. //! ## Compatibility
  13. //!
  14. //! The `num-traits` crate is tested for rustc 1.8 and greater.
  15. #![doc(html_root_url = "https://docs.rs/num-traits/0.2")]
  16. #![deny(unconditional_recursion)]
  17. #![no_std]
  18. #[cfg(feature = "std")]
  19. extern crate std;
  20. use core::fmt;
  21. use core::num::Wrapping;
  22. use core::ops::{Add, Div, Mul, Rem, Sub};
  23. use core::ops::{AddAssign, DivAssign, MulAssign, RemAssign, SubAssign};
  24. pub use bounds::Bounded;
  25. #[cfg(feature = "std")]
  26. pub use float::Float;
  27. pub use float::FloatConst;
  28. // pub use real::{FloatCore, Real}; // NOTE: Don't do this, it breaks `use num_traits::*;`.
  29. pub use cast::{cast, AsPrimitive, FromPrimitive, NumCast, ToPrimitive};
  30. pub use identities::{one, zero, One, Zero};
  31. pub use int::PrimInt;
  32. pub use ops::checked::{
  33. CheckedAdd, CheckedDiv, CheckedMul, CheckedNeg, CheckedRem, CheckedShl, CheckedShr, CheckedSub,
  34. };
  35. pub use ops::inv::Inv;
  36. pub use ops::mul_add::{MulAdd, MulAddAssign};
  37. pub use ops::saturating::Saturating;
  38. pub use ops::wrapping::{WrappingAdd, WrappingMul, WrappingShl, WrappingShr, WrappingSub};
  39. pub use pow::{checked_pow, pow, Pow};
  40. pub use sign::{abs, abs_sub, signum, Signed, Unsigned};
  41. #[macro_use]
  42. mod macros;
  43. pub mod bounds;
  44. pub mod cast;
  45. pub mod float;
  46. pub mod identities;
  47. pub mod int;
  48. pub mod ops;
  49. pub mod pow;
  50. #[cfg(feature = "std")]
  51. pub mod real;
  52. pub mod sign;
  53. /// The base trait for numeric types, covering `0` and `1` values,
  54. /// comparisons, basic numeric operations, and string conversion.
  55. pub trait Num: PartialEq + Zero + One + NumOps {
  56. type FromStrRadixErr;
  57. /// Convert from a string and radix <= 36.
  58. ///
  59. /// # Examples
  60. ///
  61. /// ```rust
  62. /// use num_traits::Num;
  63. ///
  64. /// let result = <i32 as Num>::from_str_radix("27", 10);
  65. /// assert_eq!(result, Ok(27));
  66. ///
  67. /// let result = <i32 as Num>::from_str_radix("foo", 10);
  68. /// assert!(result.is_err());
  69. /// ```
  70. fn from_str_radix(str: &str, radix: u32) -> Result<Self, Self::FromStrRadixErr>;
  71. }
  72. /// The trait for types implementing basic numeric operations
  73. ///
  74. /// This is automatically implemented for types which implement the operators.
  75. pub trait NumOps<Rhs = Self, Output = Self>:
  76. Add<Rhs, Output = Output>
  77. + Sub<Rhs, Output = Output>
  78. + Mul<Rhs, Output = Output>
  79. + Div<Rhs, Output = Output>
  80. + Rem<Rhs, Output = Output>
  81. {
  82. }
  83. impl<T, Rhs, Output> NumOps<Rhs, Output> for T where
  84. T: Add<Rhs, Output = Output>
  85. + Sub<Rhs, Output = Output>
  86. + Mul<Rhs, Output = Output>
  87. + Div<Rhs, Output = Output>
  88. + Rem<Rhs, Output = Output>
  89. {
  90. }
  91. /// The trait for `Num` types which also implement numeric operations taking
  92. /// the second operand by reference.
  93. ///
  94. /// This is automatically implemented for types which implement the operators.
  95. pub trait NumRef: Num + for<'r> NumOps<&'r Self> {}
  96. impl<T> NumRef for T where T: Num + for<'r> NumOps<&'r T> {}
  97. /// The trait for references which implement numeric operations, taking the
  98. /// second operand either by value or by reference.
  99. ///
  100. /// This is automatically implemented for types which implement the operators.
  101. pub trait RefNum<Base>: NumOps<Base, Base> + for<'r> NumOps<&'r Base, Base> {}
  102. impl<T, Base> RefNum<Base> for T where T: NumOps<Base, Base> + for<'r> NumOps<&'r Base, Base> {}
  103. /// The trait for types implementing numeric assignment operators (like `+=`).
  104. ///
  105. /// This is automatically implemented for types which implement the operators.
  106. pub trait NumAssignOps<Rhs = Self>:
  107. AddAssign<Rhs> + SubAssign<Rhs> + MulAssign<Rhs> + DivAssign<Rhs> + RemAssign<Rhs>
  108. {
  109. }
  110. impl<T, Rhs> NumAssignOps<Rhs> for T where
  111. T: AddAssign<Rhs> + SubAssign<Rhs> + MulAssign<Rhs> + DivAssign<Rhs> + RemAssign<Rhs>
  112. {
  113. }
  114. /// The trait for `Num` types which also implement assignment operators.
  115. ///
  116. /// This is automatically implemented for types which implement the operators.
  117. pub trait NumAssign: Num + NumAssignOps {}
  118. impl<T> NumAssign for T where T: Num + NumAssignOps {}
  119. /// The trait for `NumAssign` types which also implement assignment operations
  120. /// taking the second operand by reference.
  121. ///
  122. /// This is automatically implemented for types which implement the operators.
  123. pub trait NumAssignRef: NumAssign + for<'r> NumAssignOps<&'r Self> {}
  124. impl<T> NumAssignRef for T where T: NumAssign + for<'r> NumAssignOps<&'r T> {}
  125. macro_rules! int_trait_impl {
  126. ($name:ident for $($t:ty)*) => ($(
  127. impl $name for $t {
  128. type FromStrRadixErr = ::core::num::ParseIntError;
  129. #[inline]
  130. fn from_str_radix(s: &str, radix: u32)
  131. -> Result<Self, ::core::num::ParseIntError>
  132. {
  133. <$t>::from_str_radix(s, radix)
  134. }
  135. }
  136. )*)
  137. }
  138. int_trait_impl!(Num for usize u8 u16 u32 u64 isize i8 i16 i32 i64);
  139. #[cfg(has_i128)]
  140. int_trait_impl!(Num for u128 i128);
  141. impl<T: Num> Num for Wrapping<T>
  142. where
  143. Wrapping<T>: Add<Output = Wrapping<T>>
  144. + Sub<Output = Wrapping<T>>
  145. + Mul<Output = Wrapping<T>>
  146. + Div<Output = Wrapping<T>>
  147. + Rem<Output = Wrapping<T>>,
  148. {
  149. type FromStrRadixErr = T::FromStrRadixErr;
  150. fn from_str_radix(str: &str, radix: u32) -> Result<Self, Self::FromStrRadixErr> {
  151. T::from_str_radix(str, radix).map(Wrapping)
  152. }
  153. }
  154. #[derive(Debug)]
  155. pub enum FloatErrorKind {
  156. Empty,
  157. Invalid,
  158. }
  159. // FIXME: core::num::ParseFloatError is stable in 1.0, but opaque to us,
  160. // so there's not really any way for us to reuse it.
  161. #[derive(Debug)]
  162. pub struct ParseFloatError {
  163. pub kind: FloatErrorKind,
  164. }
  165. impl fmt::Display for ParseFloatError {
  166. fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
  167. let description = match self.kind {
  168. FloatErrorKind::Empty => "cannot parse float from empty string",
  169. FloatErrorKind::Invalid => "invalid float literal",
  170. };
  171. description.fmt(f)
  172. }
  173. }
  174. // FIXME: The standard library from_str_radix on floats was deprecated, so we're stuck
  175. // with this implementation ourselves until we want to make a breaking change.
  176. // (would have to drop it from `Num` though)
  177. macro_rules! float_trait_impl {
  178. ($name:ident for $($t:ident)*) => ($(
  179. impl $name for $t {
  180. type FromStrRadixErr = ParseFloatError;
  181. fn from_str_radix(src: &str, radix: u32)
  182. -> Result<Self, Self::FromStrRadixErr>
  183. {
  184. use self::FloatErrorKind::*;
  185. use self::ParseFloatError as PFE;
  186. // Special values
  187. match src {
  188. "inf" => return Ok(core::$t::INFINITY),
  189. "-inf" => return Ok(core::$t::NEG_INFINITY),
  190. "NaN" => return Ok(core::$t::NAN),
  191. _ => {},
  192. }
  193. fn slice_shift_char(src: &str) -> Option<(char, &str)> {
  194. src.chars().nth(0).map(|ch| (ch, &src[1..]))
  195. }
  196. let (is_positive, src) = match slice_shift_char(src) {
  197. None => return Err(PFE { kind: Empty }),
  198. Some(('-', "")) => return Err(PFE { kind: Empty }),
  199. Some(('-', src)) => (false, src),
  200. Some((_, _)) => (true, src),
  201. };
  202. // The significand to accumulate
  203. let mut sig = if is_positive { 0.0 } else { -0.0 };
  204. // Necessary to detect overflow
  205. let mut prev_sig = sig;
  206. let mut cs = src.chars().enumerate();
  207. // Exponent prefix and exponent index offset
  208. let mut exp_info = None::<(char, usize)>;
  209. // Parse the integer part of the significand
  210. for (i, c) in cs.by_ref() {
  211. match c.to_digit(radix) {
  212. Some(digit) => {
  213. // shift significand one digit left
  214. sig = sig * (radix as $t);
  215. // add/subtract current digit depending on sign
  216. if is_positive {
  217. sig = sig + ((digit as isize) as $t);
  218. } else {
  219. sig = sig - ((digit as isize) as $t);
  220. }
  221. // Detect overflow by comparing to last value, except
  222. // if we've not seen any non-zero digits.
  223. if prev_sig != 0.0 {
  224. if is_positive && sig <= prev_sig
  225. { return Ok(core::$t::INFINITY); }
  226. if !is_positive && sig >= prev_sig
  227. { return Ok(core::$t::NEG_INFINITY); }
  228. // Detect overflow by reversing the shift-and-add process
  229. if is_positive && (prev_sig != (sig - digit as $t) / radix as $t)
  230. { return Ok(core::$t::INFINITY); }
  231. if !is_positive && (prev_sig != (sig + digit as $t) / radix as $t)
  232. { return Ok(core::$t::NEG_INFINITY); }
  233. }
  234. prev_sig = sig;
  235. },
  236. None => match c {
  237. 'e' | 'E' | 'p' | 'P' => {
  238. exp_info = Some((c, i + 1));
  239. break; // start of exponent
  240. },
  241. '.' => {
  242. break; // start of fractional part
  243. },
  244. _ => {
  245. return Err(PFE { kind: Invalid });
  246. },
  247. },
  248. }
  249. }
  250. // If we are not yet at the exponent parse the fractional
  251. // part of the significand
  252. if exp_info.is_none() {
  253. let mut power = 1.0;
  254. for (i, c) in cs.by_ref() {
  255. match c.to_digit(radix) {
  256. Some(digit) => {
  257. // Decrease power one order of magnitude
  258. power = power / (radix as $t);
  259. // add/subtract current digit depending on sign
  260. sig = if is_positive {
  261. sig + (digit as $t) * power
  262. } else {
  263. sig - (digit as $t) * power
  264. };
  265. // Detect overflow by comparing to last value
  266. if is_positive && sig < prev_sig
  267. { return Ok(core::$t::INFINITY); }
  268. if !is_positive && sig > prev_sig
  269. { return Ok(core::$t::NEG_INFINITY); }
  270. prev_sig = sig;
  271. },
  272. None => match c {
  273. 'e' | 'E' | 'p' | 'P' => {
  274. exp_info = Some((c, i + 1));
  275. break; // start of exponent
  276. },
  277. _ => {
  278. return Err(PFE { kind: Invalid });
  279. },
  280. },
  281. }
  282. }
  283. }
  284. // Parse and calculate the exponent
  285. let exp = match exp_info {
  286. Some((c, offset)) => {
  287. let base = match c {
  288. 'E' | 'e' if radix == 10 => 10.0,
  289. 'P' | 'p' if radix == 16 => 2.0,
  290. _ => return Err(PFE { kind: Invalid }),
  291. };
  292. // Parse the exponent as decimal integer
  293. let src = &src[offset..];
  294. let (is_positive, exp) = match slice_shift_char(src) {
  295. Some(('-', src)) => (false, src.parse::<usize>()),
  296. Some(('+', src)) => (true, src.parse::<usize>()),
  297. Some((_, _)) => (true, src.parse::<usize>()),
  298. None => return Err(PFE { kind: Invalid }),
  299. };
  300. #[cfg(feature = "std")]
  301. fn pow(base: $t, exp: usize) -> $t {
  302. Float::powi(base, exp as i32)
  303. }
  304. // otherwise uses the generic `pow` from the root
  305. match (is_positive, exp) {
  306. (true, Ok(exp)) => pow(base, exp),
  307. (false, Ok(exp)) => 1.0 / pow(base, exp),
  308. (_, Err(_)) => return Err(PFE { kind: Invalid }),
  309. }
  310. },
  311. None => 1.0, // no exponent
  312. };
  313. Ok(sig * exp)
  314. }
  315. }
  316. )*)
  317. }
  318. float_trait_impl!(Num for f32 f64);
  319. /// A value bounded by a minimum and a maximum
  320. ///
  321. /// If input is less than min then this returns min.
  322. /// If input is greater than max then this returns max.
  323. /// Otherwise this returns input.
  324. #[inline]
  325. pub fn clamp<T: PartialOrd>(input: T, min: T, max: T) -> T {
  326. debug_assert!(min <= max, "min must be less than or equal to max");
  327. if input < min {
  328. min
  329. } else if input > max {
  330. max
  331. } else {
  332. input
  333. }
  334. }
  335. /// A value bounded by a minimum value
  336. ///
  337. /// If input is less than min then this returns min.
  338. /// Otherwise this returns input.
  339. /// `clamp_min(std::f32::NAN, 1.0)` preserves `NAN` different from `f32::min(std::f32::NAN, 1.0)`.
  340. #[inline]
  341. pub fn clamp_min<T: PartialOrd>(input: T, min: T) -> T {
  342. if input < min {
  343. min
  344. } else {
  345. input
  346. }
  347. }
  348. /// A value bounded by a maximum value
  349. ///
  350. /// If input is less than min then this returns min.
  351. /// Otherwise this returns input.
  352. /// `clamp_max(std::f32::NAN, 1.0)` preserves `NAN` different from `f32::max(std::f32::NAN, 1.0)`.
  353. #[inline]
  354. pub fn clamp_max<T: PartialOrd>(input: T, max: T) -> T {
  355. if input > max {
  356. max
  357. } else {
  358. input
  359. }
  360. }
  361. #[test]
  362. fn clamp_test() {
  363. // Int test
  364. assert_eq!(1, clamp(1, -1, 2));
  365. assert_eq!(-1, clamp(-2, -1, 2));
  366. assert_eq!(2, clamp(3, -1, 2));
  367. assert_eq!(1, clamp_min(1, -1));
  368. assert_eq!(-1, clamp_min(-2, -1));
  369. assert_eq!(-1, clamp_max(1, -1));
  370. assert_eq!(-2, clamp_max(-2, -1));
  371. // Float test
  372. assert_eq!(1.0, clamp(1.0, -1.0, 2.0));
  373. assert_eq!(-1.0, clamp(-2.0, -1.0, 2.0));
  374. assert_eq!(2.0, clamp(3.0, -1.0, 2.0));
  375. assert_eq!(1.0, clamp_min(1.0, -1.0));
  376. assert_eq!(-1.0, clamp_min(-2.0, -1.0));
  377. assert_eq!(-1.0, clamp_max(1.0, -1.0));
  378. assert_eq!(-2.0, clamp_max(-2.0, -1.0));
  379. assert!(clamp(::core::f32::NAN, -1.0, 1.0).is_nan());
  380. assert!(clamp_min(::core::f32::NAN, 1.0).is_nan());
  381. assert!(clamp_max(::core::f32::NAN, 1.0).is_nan());
  382. }
  383. #[test]
  384. fn from_str_radix_unwrap() {
  385. // The Result error must impl Debug to allow unwrap()
  386. let i: i32 = Num::from_str_radix("0", 10).unwrap();
  387. assert_eq!(i, 0);
  388. let f: f32 = Num::from_str_radix("0.0", 10).unwrap();
  389. assert_eq!(f, 0.0);
  390. }
  391. #[test]
  392. fn wrapping_is_num() {
  393. fn require_num<T: Num>(_: &T) {}
  394. require_num(&Wrapping(42_u32));
  395. require_num(&Wrapping(-42));
  396. }
  397. #[test]
  398. fn wrapping_from_str_radix() {
  399. macro_rules! test_wrapping_from_str_radix {
  400. ($($t:ty)+) => {
  401. $(
  402. for &(s, r) in &[("42", 10), ("42", 2), ("-13.0", 10), ("foo", 10)] {
  403. let w = Wrapping::<$t>::from_str_radix(s, r).map(|w| w.0);
  404. assert_eq!(w, <$t as Num>::from_str_radix(s, r));
  405. }
  406. )+
  407. };
  408. }
  409. test_wrapping_from_str_radix!(usize u8 u16 u32 u64 isize i8 i16 i32 i64);
  410. }
  411. #[test]
  412. fn check_num_ops() {
  413. fn compute<T: Num + Copy>(x: T, y: T) -> T {
  414. x * y / y % y + y - y
  415. }
  416. assert_eq!(compute(1, 2), 1)
  417. }
  418. #[test]
  419. fn check_numref_ops() {
  420. fn compute<T: NumRef>(x: T, y: &T) -> T {
  421. x * y / y % y + y - y
  422. }
  423. assert_eq!(compute(1, &2), 1)
  424. }
  425. #[test]
  426. fn check_refnum_ops() {
  427. fn compute<T: Copy>(x: &T, y: T) -> T
  428. where
  429. for<'a> &'a T: RefNum<T>,
  430. {
  431. &(&(&(&(x * y) / y) % y) + y) - y
  432. }
  433. assert_eq!(compute(&1, 2), 1)
  434. }
  435. #[test]
  436. fn check_refref_ops() {
  437. fn compute<T>(x: &T, y: &T) -> T
  438. where
  439. for<'a> &'a T: RefNum<T>,
  440. {
  441. &(&(&(&(x * y) / y) % y) + y) - y
  442. }
  443. assert_eq!(compute(&1, &2), 1)
  444. }
  445. #[test]
  446. fn check_numassign_ops() {
  447. fn compute<T: NumAssign + Copy>(mut x: T, y: T) -> T {
  448. x *= y;
  449. x /= y;
  450. x %= y;
  451. x += y;
  452. x -= y;
  453. x
  454. }
  455. assert_eq!(compute(1, 2), 1)
  456. }
  457. // TODO test `NumAssignRef`, but even the standard numeric types don't
  458. // implement this yet. (see rust pr41336)