lib.rs 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594
  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. // Only `no_std` builds actually use `libm`.
  21. #[cfg(all(not(feature = "std"), feature = "libm"))]
  22. extern crate libm;
  23. use core::fmt;
  24. use core::num::Wrapping;
  25. use core::ops::{Add, Div, Mul, Rem, Sub};
  26. use core::ops::{AddAssign, DivAssign, MulAssign, RemAssign, SubAssign};
  27. pub use bounds::Bounded;
  28. #[cfg(any(feature = "std", feature = "libm"))]
  29. pub use float::Float;
  30. pub use float::FloatConst;
  31. // pub use real::{FloatCore, Real}; // NOTE: Don't do this, it breaks `use num_traits::*;`.
  32. pub use cast::{cast, AsPrimitive, FromPrimitive, NumCast, ToPrimitive};
  33. pub use identities::{one, zero, One, Zero};
  34. pub use int::PrimInt;
  35. pub use ops::checked::{
  36. CheckedAdd, CheckedDiv, CheckedMul, CheckedNeg, CheckedRem, CheckedShl, CheckedShr, CheckedSub,
  37. };
  38. pub use ops::inv::Inv;
  39. pub use ops::mul_add::{MulAdd, MulAddAssign};
  40. pub use ops::saturating::{Saturating, SaturatingAdd, SaturatingMul, SaturatingSub};
  41. pub use ops::wrapping::{
  42. WrappingAdd, WrappingMul, WrappingNeg, WrappingShl, WrappingShr, WrappingSub,
  43. };
  44. pub use pow::{checked_pow, pow, Pow};
  45. pub use sign::{abs, abs_sub, signum, Signed, Unsigned};
  46. #[macro_use]
  47. mod macros;
  48. pub mod bounds;
  49. pub mod cast;
  50. pub mod float;
  51. pub mod identities;
  52. pub mod int;
  53. pub mod ops;
  54. pub mod pow;
  55. pub mod real;
  56. pub mod sign;
  57. /// The base trait for numeric types, covering `0` and `1` values,
  58. /// comparisons, basic numeric operations, and string conversion.
  59. pub trait Num: PartialEq + Zero + One + NumOps {
  60. type FromStrRadixErr;
  61. /// Convert from a string and radix (typically `2..=36`).
  62. ///
  63. /// # Examples
  64. ///
  65. /// ```rust
  66. /// use num_traits::Num;
  67. ///
  68. /// let result = <i32 as Num>::from_str_radix("27", 10);
  69. /// assert_eq!(result, Ok(27));
  70. ///
  71. /// let result = <i32 as Num>::from_str_radix("foo", 10);
  72. /// assert!(result.is_err());
  73. /// ```
  74. ///
  75. /// # Supported radices
  76. ///
  77. /// The exact range of supported radices is at the discretion of each type implementation. For
  78. /// primitive integers, this is implemented by the inherent `from_str_radix` methods in the
  79. /// standard library, which **panic** if the radix is not in the range from 2 to 36. The
  80. /// implementation in this crate for primitive floats is similar.
  81. ///
  82. /// For third-party types, it is suggested that implementations should follow suit and at least
  83. /// accept `2..=36` without panicking, but an `Err` may be returned for any unsupported radix.
  84. /// It's possible that a type might not even support the common radix 10, nor any, if string
  85. /// parsing doesn't make sense for that type.
  86. fn from_str_radix(str: &str, radix: u32) -> Result<Self, Self::FromStrRadixErr>;
  87. }
  88. /// The trait for types implementing basic numeric operations
  89. ///
  90. /// This is automatically implemented for types which implement the operators.
  91. pub trait NumOps<Rhs = Self, Output = Self>:
  92. Add<Rhs, Output = Output>
  93. + Sub<Rhs, Output = Output>
  94. + Mul<Rhs, Output = Output>
  95. + Div<Rhs, Output = Output>
  96. + Rem<Rhs, Output = Output>
  97. {
  98. }
  99. impl<T, Rhs, Output> NumOps<Rhs, Output> for T where
  100. T: Add<Rhs, Output = Output>
  101. + Sub<Rhs, Output = Output>
  102. + Mul<Rhs, Output = Output>
  103. + Div<Rhs, Output = Output>
  104. + Rem<Rhs, Output = Output>
  105. {
  106. }
  107. /// The trait for `Num` types which also implement numeric operations taking
  108. /// the second operand by reference.
  109. ///
  110. /// This is automatically implemented for types which implement the operators.
  111. pub trait NumRef: Num + for<'r> NumOps<&'r Self> {}
  112. impl<T> NumRef for T where T: Num + for<'r> NumOps<&'r T> {}
  113. /// The trait for references which implement numeric operations, taking the
  114. /// second operand either by value or by reference.
  115. ///
  116. /// This is automatically implemented for types which implement the operators.
  117. pub trait RefNum<Base>: NumOps<Base, Base> + for<'r> NumOps<&'r Base, Base> {}
  118. impl<T, Base> RefNum<Base> for T where T: NumOps<Base, Base> + for<'r> NumOps<&'r Base, Base> {}
  119. /// The trait for types implementing numeric assignment operators (like `+=`).
  120. ///
  121. /// This is automatically implemented for types which implement the operators.
  122. pub trait NumAssignOps<Rhs = Self>:
  123. AddAssign<Rhs> + SubAssign<Rhs> + MulAssign<Rhs> + DivAssign<Rhs> + RemAssign<Rhs>
  124. {
  125. }
  126. impl<T, Rhs> NumAssignOps<Rhs> for T where
  127. T: AddAssign<Rhs> + SubAssign<Rhs> + MulAssign<Rhs> + DivAssign<Rhs> + RemAssign<Rhs>
  128. {
  129. }
  130. /// The trait for `Num` types which also implement assignment operators.
  131. ///
  132. /// This is automatically implemented for types which implement the operators.
  133. pub trait NumAssign: Num + NumAssignOps {}
  134. impl<T> NumAssign for T where T: Num + NumAssignOps {}
  135. /// The trait for `NumAssign` types which also implement assignment operations
  136. /// taking the second operand by reference.
  137. ///
  138. /// This is automatically implemented for types which implement the operators.
  139. pub trait NumAssignRef: NumAssign + for<'r> NumAssignOps<&'r Self> {}
  140. impl<T> NumAssignRef for T where T: NumAssign + for<'r> NumAssignOps<&'r T> {}
  141. macro_rules! int_trait_impl {
  142. ($name:ident for $($t:ty)*) => ($(
  143. impl $name for $t {
  144. type FromStrRadixErr = ::core::num::ParseIntError;
  145. #[inline]
  146. fn from_str_radix(s: &str, radix: u32)
  147. -> Result<Self, ::core::num::ParseIntError>
  148. {
  149. <$t>::from_str_radix(s, radix)
  150. }
  151. }
  152. )*)
  153. }
  154. int_trait_impl!(Num for usize u8 u16 u32 u64 isize i8 i16 i32 i64);
  155. #[cfg(has_i128)]
  156. int_trait_impl!(Num for u128 i128);
  157. impl<T: Num> Num for Wrapping<T>
  158. where
  159. Wrapping<T>: Add<Output = Wrapping<T>>
  160. + Sub<Output = Wrapping<T>>
  161. + Mul<Output = Wrapping<T>>
  162. + Div<Output = Wrapping<T>>
  163. + Rem<Output = Wrapping<T>>,
  164. {
  165. type FromStrRadixErr = T::FromStrRadixErr;
  166. fn from_str_radix(str: &str, radix: u32) -> Result<Self, Self::FromStrRadixErr> {
  167. T::from_str_radix(str, radix).map(Wrapping)
  168. }
  169. }
  170. #[derive(Debug)]
  171. pub enum FloatErrorKind {
  172. Empty,
  173. Invalid,
  174. }
  175. // FIXME: core::num::ParseFloatError is stable in 1.0, but opaque to us,
  176. // so there's not really any way for us to reuse it.
  177. #[derive(Debug)]
  178. pub struct ParseFloatError {
  179. pub kind: FloatErrorKind,
  180. }
  181. impl fmt::Display for ParseFloatError {
  182. fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
  183. let description = match self.kind {
  184. FloatErrorKind::Empty => "cannot parse float from empty string",
  185. FloatErrorKind::Invalid => "invalid float literal",
  186. };
  187. description.fmt(f)
  188. }
  189. }
  190. // FIXME: The standard library from_str_radix on floats was deprecated, so we're stuck
  191. // with this implementation ourselves until we want to make a breaking change.
  192. // (would have to drop it from `Num` though)
  193. macro_rules! float_trait_impl {
  194. ($name:ident for $($t:ident)*) => ($(
  195. impl $name for $t {
  196. type FromStrRadixErr = ParseFloatError;
  197. fn from_str_radix(src: &str, radix: u32)
  198. -> Result<Self, Self::FromStrRadixErr>
  199. {
  200. use self::FloatErrorKind::*;
  201. use self::ParseFloatError as PFE;
  202. // Special case radix 10 to use more accurate standard library implementation
  203. if radix == 10 {
  204. return src.parse().map_err(|_| PFE {
  205. kind: if src.is_empty() { Empty } else { Invalid },
  206. });
  207. }
  208. // Special values
  209. match src {
  210. "inf" => return Ok(core::$t::INFINITY),
  211. "-inf" => return Ok(core::$t::NEG_INFINITY),
  212. "NaN" => return Ok(core::$t::NAN),
  213. "-NaN" => return Ok(-core::$t::NAN),
  214. _ => {},
  215. }
  216. fn slice_shift_char(src: &str) -> Option<(char, &str)> {
  217. let mut chars = src.chars();
  218. if let Some(ch) = chars.next() {
  219. Some((ch, chars.as_str()))
  220. } else {
  221. None
  222. }
  223. }
  224. let (is_positive, src) = match slice_shift_char(src) {
  225. None => return Err(PFE { kind: Empty }),
  226. Some(('-', "")) => return Err(PFE { kind: Empty }),
  227. Some(('-', src)) => (false, src),
  228. Some((_, _)) => (true, src),
  229. };
  230. // The significand to accumulate
  231. let mut sig = if is_positive { 0.0 } else { -0.0 };
  232. // Necessary to detect overflow
  233. let mut prev_sig = sig;
  234. let mut cs = src.chars().enumerate();
  235. // Exponent prefix and exponent index offset
  236. let mut exp_info = None::<(char, usize)>;
  237. // Parse the integer part of the significand
  238. for (i, c) in cs.by_ref() {
  239. match c.to_digit(radix) {
  240. Some(digit) => {
  241. // shift significand one digit left
  242. sig = sig * (radix as $t);
  243. // add/subtract current digit depending on sign
  244. if is_positive {
  245. sig = sig + ((digit as isize) as $t);
  246. } else {
  247. sig = sig - ((digit as isize) as $t);
  248. }
  249. // Detect overflow by comparing to last value, except
  250. // if we've not seen any non-zero digits.
  251. if prev_sig != 0.0 {
  252. if is_positive && sig <= prev_sig
  253. { return Ok(core::$t::INFINITY); }
  254. if !is_positive && sig >= prev_sig
  255. { return Ok(core::$t::NEG_INFINITY); }
  256. // Detect overflow by reversing the shift-and-add process
  257. if is_positive && (prev_sig != (sig - digit as $t) / radix as $t)
  258. { return Ok(core::$t::INFINITY); }
  259. if !is_positive && (prev_sig != (sig + digit as $t) / radix as $t)
  260. { return Ok(core::$t::NEG_INFINITY); }
  261. }
  262. prev_sig = sig;
  263. },
  264. None => match c {
  265. 'e' | 'E' | 'p' | 'P' => {
  266. exp_info = Some((c, i + 1));
  267. break; // start of exponent
  268. },
  269. '.' => {
  270. break; // start of fractional part
  271. },
  272. _ => {
  273. return Err(PFE { kind: Invalid });
  274. },
  275. },
  276. }
  277. }
  278. // If we are not yet at the exponent parse the fractional
  279. // part of the significand
  280. if exp_info.is_none() {
  281. let mut power = 1.0;
  282. for (i, c) in cs.by_ref() {
  283. match c.to_digit(radix) {
  284. Some(digit) => {
  285. // Decrease power one order of magnitude
  286. power = power / (radix as $t);
  287. // add/subtract current digit depending on sign
  288. sig = if is_positive {
  289. sig + (digit as $t) * power
  290. } else {
  291. sig - (digit as $t) * power
  292. };
  293. // Detect overflow by comparing to last value
  294. if is_positive && sig < prev_sig
  295. { return Ok(core::$t::INFINITY); }
  296. if !is_positive && sig > prev_sig
  297. { return Ok(core::$t::NEG_INFINITY); }
  298. prev_sig = sig;
  299. },
  300. None => match c {
  301. 'e' | 'E' | 'p' | 'P' => {
  302. exp_info = Some((c, i + 1));
  303. break; // start of exponent
  304. },
  305. _ => {
  306. return Err(PFE { kind: Invalid });
  307. },
  308. },
  309. }
  310. }
  311. }
  312. // Parse and calculate the exponent
  313. let exp = match exp_info {
  314. Some((c, offset)) => {
  315. let base = match c {
  316. 'E' | 'e' if radix == 10 => 10.0,
  317. 'P' | 'p' if radix == 16 => 2.0,
  318. _ => return Err(PFE { kind: Invalid }),
  319. };
  320. // Parse the exponent as decimal integer
  321. let src = &src[offset..];
  322. let (is_positive, exp) = match slice_shift_char(src) {
  323. Some(('-', src)) => (false, src.parse::<usize>()),
  324. Some(('+', src)) => (true, src.parse::<usize>()),
  325. Some((_, _)) => (true, src.parse::<usize>()),
  326. None => return Err(PFE { kind: Invalid }),
  327. };
  328. #[cfg(feature = "std")]
  329. fn pow(base: $t, exp: usize) -> $t {
  330. Float::powi(base, exp as i32)
  331. }
  332. // otherwise uses the generic `pow` from the root
  333. match (is_positive, exp) {
  334. (true, Ok(exp)) => pow(base, exp),
  335. (false, Ok(exp)) => 1.0 / pow(base, exp),
  336. (_, Err(_)) => return Err(PFE { kind: Invalid }),
  337. }
  338. },
  339. None => 1.0, // no exponent
  340. };
  341. Ok(sig * exp)
  342. }
  343. }
  344. )*)
  345. }
  346. float_trait_impl!(Num for f32 f64);
  347. /// A value bounded by a minimum and a maximum
  348. ///
  349. /// If input is less than min then this returns min.
  350. /// If input is greater than max then this returns max.
  351. /// Otherwise this returns input.
  352. ///
  353. /// **Panics** in debug mode if `!(min <= max)`.
  354. #[inline]
  355. pub fn clamp<T: PartialOrd>(input: T, min: T, max: T) -> T {
  356. debug_assert!(min <= max, "min must be less than or equal to max");
  357. if input < min {
  358. min
  359. } else if input > max {
  360. max
  361. } else {
  362. input
  363. }
  364. }
  365. /// A value bounded by a minimum value
  366. ///
  367. /// If input is less than min then this returns min.
  368. /// Otherwise this returns input.
  369. /// `clamp_min(std::f32::NAN, 1.0)` preserves `NAN` different from `f32::min(std::f32::NAN, 1.0)`.
  370. ///
  371. /// **Panics** in debug mode if `!(min == min)`. (This occurs if `min` is `NAN`.)
  372. #[inline]
  373. pub fn clamp_min<T: PartialOrd>(input: T, min: T) -> T {
  374. debug_assert!(min == min, "min must not be NAN");
  375. if input < min {
  376. min
  377. } else {
  378. input
  379. }
  380. }
  381. /// A value bounded by a maximum value
  382. ///
  383. /// If input is greater than max then this returns max.
  384. /// Otherwise this returns input.
  385. /// `clamp_max(std::f32::NAN, 1.0)` preserves `NAN` different from `f32::max(std::f32::NAN, 1.0)`.
  386. ///
  387. /// **Panics** in debug mode if `!(max == max)`. (This occurs if `max` is `NAN`.)
  388. #[inline]
  389. pub fn clamp_max<T: PartialOrd>(input: T, max: T) -> T {
  390. debug_assert!(max == max, "max must not be NAN");
  391. if input > max {
  392. max
  393. } else {
  394. input
  395. }
  396. }
  397. #[test]
  398. fn clamp_test() {
  399. // Int test
  400. assert_eq!(1, clamp(1, -1, 2));
  401. assert_eq!(-1, clamp(-2, -1, 2));
  402. assert_eq!(2, clamp(3, -1, 2));
  403. assert_eq!(1, clamp_min(1, -1));
  404. assert_eq!(-1, clamp_min(-2, -1));
  405. assert_eq!(-1, clamp_max(1, -1));
  406. assert_eq!(-2, clamp_max(-2, -1));
  407. // Float test
  408. assert_eq!(1.0, clamp(1.0, -1.0, 2.0));
  409. assert_eq!(-1.0, clamp(-2.0, -1.0, 2.0));
  410. assert_eq!(2.0, clamp(3.0, -1.0, 2.0));
  411. assert_eq!(1.0, clamp_min(1.0, -1.0));
  412. assert_eq!(-1.0, clamp_min(-2.0, -1.0));
  413. assert_eq!(-1.0, clamp_max(1.0, -1.0));
  414. assert_eq!(-2.0, clamp_max(-2.0, -1.0));
  415. assert!(clamp(::core::f32::NAN, -1.0, 1.0).is_nan());
  416. assert!(clamp_min(::core::f32::NAN, 1.0).is_nan());
  417. assert!(clamp_max(::core::f32::NAN, 1.0).is_nan());
  418. }
  419. #[test]
  420. #[should_panic]
  421. #[cfg(debug_assertions)]
  422. fn clamp_nan_min() {
  423. clamp(0., ::core::f32::NAN, 1.);
  424. }
  425. #[test]
  426. #[should_panic]
  427. #[cfg(debug_assertions)]
  428. fn clamp_nan_max() {
  429. clamp(0., -1., ::core::f32::NAN);
  430. }
  431. #[test]
  432. #[should_panic]
  433. #[cfg(debug_assertions)]
  434. fn clamp_nan_min_max() {
  435. clamp(0., ::core::f32::NAN, ::core::f32::NAN);
  436. }
  437. #[test]
  438. #[should_panic]
  439. #[cfg(debug_assertions)]
  440. fn clamp_min_nan_min() {
  441. clamp_min(0., ::core::f32::NAN);
  442. }
  443. #[test]
  444. #[should_panic]
  445. #[cfg(debug_assertions)]
  446. fn clamp_max_nan_max() {
  447. clamp_max(0., ::core::f32::NAN);
  448. }
  449. #[test]
  450. fn from_str_radix_unwrap() {
  451. // The Result error must impl Debug to allow unwrap()
  452. let i: i32 = Num::from_str_radix("0", 10).unwrap();
  453. assert_eq!(i, 0);
  454. let f: f32 = Num::from_str_radix("0.0", 10).unwrap();
  455. assert_eq!(f, 0.0);
  456. }
  457. #[test]
  458. fn from_str_radix_multi_byte_fail() {
  459. // Ensure parsing doesn't panic, even on invalid sign characters
  460. assert!(f32::from_str_radix("™0.2", 10).is_err());
  461. // Even when parsing the exponent sign
  462. assert!(f32::from_str_radix("0.2E™1", 10).is_err());
  463. }
  464. #[test]
  465. fn wrapping_is_num() {
  466. fn require_num<T: Num>(_: &T) {}
  467. require_num(&Wrapping(42_u32));
  468. require_num(&Wrapping(-42));
  469. }
  470. #[test]
  471. fn wrapping_from_str_radix() {
  472. macro_rules! test_wrapping_from_str_radix {
  473. ($($t:ty)+) => {
  474. $(
  475. for &(s, r) in &[("42", 10), ("42", 2), ("-13.0", 10), ("foo", 10)] {
  476. let w = Wrapping::<$t>::from_str_radix(s, r).map(|w| w.0);
  477. assert_eq!(w, <$t as Num>::from_str_radix(s, r));
  478. }
  479. )+
  480. };
  481. }
  482. test_wrapping_from_str_radix!(usize u8 u16 u32 u64 isize i8 i16 i32 i64);
  483. }
  484. #[test]
  485. fn check_num_ops() {
  486. fn compute<T: Num + Copy>(x: T, y: T) -> T {
  487. x * y / y % y + y - y
  488. }
  489. assert_eq!(compute(1, 2), 1)
  490. }
  491. #[test]
  492. fn check_numref_ops() {
  493. fn compute<T: NumRef>(x: T, y: &T) -> T {
  494. x * y / y % y + y - y
  495. }
  496. assert_eq!(compute(1, &2), 1)
  497. }
  498. #[test]
  499. fn check_refnum_ops() {
  500. fn compute<T: Copy>(x: &T, y: T) -> T
  501. where
  502. for<'a> &'a T: RefNum<T>,
  503. {
  504. &(&(&(&(x * y) / y) % y) + y) - y
  505. }
  506. assert_eq!(compute(&1, 2), 1)
  507. }
  508. #[test]
  509. fn check_refref_ops() {
  510. fn compute<T>(x: &T, y: &T) -> T
  511. where
  512. for<'a> &'a T: RefNum<T>,
  513. {
  514. &(&(&(&(x * y) / y) % y) + y) - y
  515. }
  516. assert_eq!(compute(&1, &2), 1)
  517. }
  518. #[test]
  519. fn check_numassign_ops() {
  520. fn compute<T: NumAssign + Copy>(mut x: T, y: T) -> T {
  521. x *= y;
  522. x /= y;
  523. x %= y;
  524. x += y;
  525. x -= y;
  526. x
  527. }
  528. assert_eq!(compute(1, 2), 1)
  529. }
  530. // TODO test `NumAssignRef`, but even the standard numeric types don't
  531. // implement this yet. (see rust pr41336)