lib.rs 15 KB

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