traits.rs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514
  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. use std::intrinsics;
  12. use std::{uint, u8, u16, u32, u64};
  13. use std::{int, i8, i16, i32, i64};
  14. use std::{f32, f64};
  15. /// The base trait for numeric types
  16. pub trait Num: PartialEq + Zero + One
  17. + Neg<Self>
  18. + Add<Self,Self>
  19. + Sub<Self,Self>
  20. + Mul<Self,Self>
  21. + Div<Self,Self>
  22. + Rem<Self,Self> {}
  23. macro_rules! trait_impl(
  24. ($name:ident for $($t:ty)*) => ($(
  25. impl $name for $t {}
  26. )*)
  27. )
  28. trait_impl!(Num for uint u8 u16 u32 u64 int i8 i16 i32 i64 f32 f64)
  29. /// Defines an additive identity element for `Self`.
  30. ///
  31. /// # Deriving
  32. ///
  33. /// This trait can be automatically be derived using `#[deriving(Zero)]`
  34. /// attribute. If you choose to use this, make sure that the laws outlined in
  35. /// the documentation for `Zero::zero` still hold.
  36. pub trait Zero: Add<Self, Self> {
  37. /// Returns the additive identity element of `Self`, `0`.
  38. ///
  39. /// # Laws
  40. ///
  41. /// ```{.text}
  42. /// a + 0 = a ∀ a ∈ Self
  43. /// 0 + a = a ∀ a ∈ Self
  44. /// ```
  45. ///
  46. /// # Purity
  47. ///
  48. /// This function should return the same result at all times regardless of
  49. /// external mutable state, for example values stored in TLS or in
  50. /// `static mut`s.
  51. // FIXME (#5527): This should be an associated constant
  52. fn zero() -> Self;
  53. /// Returns `true` if `self` is equal to the additive identity.
  54. #[inline]
  55. fn is_zero(&self) -> bool;
  56. }
  57. macro_rules! zero_impl(
  58. ($t:ty, $v:expr) => {
  59. impl Zero for $t {
  60. #[inline]
  61. fn zero() -> $t { $v }
  62. #[inline]
  63. fn is_zero(&self) -> bool { *self == $v }
  64. }
  65. }
  66. )
  67. zero_impl!(uint, 0u)
  68. zero_impl!(u8, 0u8)
  69. zero_impl!(u16, 0u16)
  70. zero_impl!(u32, 0u32)
  71. zero_impl!(u64, 0u64)
  72. zero_impl!(int, 0i)
  73. zero_impl!(i8, 0i8)
  74. zero_impl!(i16, 0i16)
  75. zero_impl!(i32, 0i32)
  76. zero_impl!(i64, 0i64)
  77. zero_impl!(f32, 0.0f32)
  78. zero_impl!(f64, 0.0f64)
  79. /// Defines a multiplicative identity element for `Self`.
  80. pub trait One: Mul<Self, Self> {
  81. /// Returns the multiplicative identity element of `Self`, `1`.
  82. ///
  83. /// # Laws
  84. ///
  85. /// ```{.text}
  86. /// a * 1 = a ∀ a ∈ Self
  87. /// 1 * a = a ∀ a ∈ Self
  88. /// ```
  89. ///
  90. /// # Purity
  91. ///
  92. /// This function should return the same result at all times regardless of
  93. /// external mutable state, for example values stored in TLS or in
  94. /// `static mut`s.
  95. // FIXME (#5527): This should be an associated constant
  96. fn one() -> Self;
  97. }
  98. macro_rules! one_impl(
  99. ($t:ty, $v:expr) => {
  100. impl One for $t {
  101. #[inline]
  102. fn one() -> $t { $v }
  103. }
  104. }
  105. )
  106. one_impl!(uint, 1u)
  107. one_impl!(u8, 1u8)
  108. one_impl!(u16, 1u16)
  109. one_impl!(u32, 1u32)
  110. one_impl!(u64, 1u64)
  111. one_impl!(int, 1i)
  112. one_impl!(i8, 1i8)
  113. one_impl!(i16, 1i16)
  114. one_impl!(i32, 1i32)
  115. one_impl!(i64, 1i64)
  116. one_impl!(f32, 1.0f32)
  117. one_impl!(f64, 1.0f64)
  118. /// Useful functions for signed numbers (i.e. numbers that can be negative).
  119. pub trait Signed: Num + Neg<Self> {
  120. /// Computes the absolute value.
  121. ///
  122. /// For `f32` and `f64`, `NaN` will be returned if the number is `NaN`.
  123. ///
  124. /// For signed integers, `::MIN` will be returned if the number is `::MIN`.
  125. fn abs(&self) -> Self;
  126. /// The positive difference of two numbers.
  127. ///
  128. /// Returns `zero` if the number is less than or equal to `other`, otherwise the difference
  129. /// between `self` and `other` is returned.
  130. fn abs_sub(&self, other: &Self) -> Self;
  131. /// Returns the sign of the number.
  132. ///
  133. /// For `f32` and `f64`:
  134. ///
  135. /// * `1.0` if the number is positive, `+0.0` or `INFINITY`
  136. /// * `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY`
  137. /// * `NaN` if the number is `NaN`
  138. ///
  139. /// For signed integers:
  140. ///
  141. /// * `0` if the number is zero
  142. /// * `1` if the number is positive
  143. /// * `-1` if the number is negative
  144. fn signum(&self) -> Self;
  145. /// Returns true if the number is positive and false if the number is zero or negative.
  146. fn is_positive(&self) -> bool;
  147. /// Returns true if the number is negative and false if the number is zero or positive.
  148. fn is_negative(&self) -> bool;
  149. }
  150. macro_rules! signed_impl(
  151. ($($t:ty)*) => ($(
  152. impl Signed for $t {
  153. #[inline]
  154. fn abs(&self) -> $t {
  155. if self.is_negative() { -*self } else { *self }
  156. }
  157. #[inline]
  158. fn abs_sub(&self, other: &$t) -> $t {
  159. if *self <= *other { 0 } else { *self - *other }
  160. }
  161. #[inline]
  162. fn signum(&self) -> $t {
  163. match *self {
  164. n if n > 0 => 1,
  165. 0 => 0,
  166. _ => -1,
  167. }
  168. }
  169. #[inline]
  170. fn is_positive(&self) -> bool { *self > 0 }
  171. #[inline]
  172. fn is_negative(&self) -> bool { *self < 0 }
  173. }
  174. )*)
  175. )
  176. signed_impl!(int i8 i16 i32 i64)
  177. macro_rules! signed_float_impl(
  178. ($t:ty, $nan:expr, $inf:expr, $neg_inf:expr, $fabs:path, $fcopysign:path, $fdim:ident) => {
  179. impl Signed for $t {
  180. /// Computes the absolute value. Returns `NAN` if the number is `NAN`.
  181. #[inline]
  182. fn abs(&self) -> $t {
  183. unsafe { $fabs(*self) }
  184. }
  185. /// The positive difference of two numbers. Returns `0.0` if the number is
  186. /// less than or equal to `other`, otherwise the difference between`self`
  187. /// and `other` is returned.
  188. #[inline]
  189. fn abs_sub(&self, other: &$t) -> $t {
  190. extern { fn $fdim(a: $t, b: $t) -> $t; }
  191. unsafe { $fdim(*self, *other) }
  192. }
  193. /// # Returns
  194. ///
  195. /// - `1.0` if the number is positive, `+0.0` or `INFINITY`
  196. /// - `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY`
  197. /// - `NAN` if the number is NaN
  198. #[inline]
  199. fn signum(&self) -> $t {
  200. if self != self { $nan } else {
  201. unsafe { $fcopysign(1.0, *self) }
  202. }
  203. }
  204. /// Returns `true` if the number is positive, including `+0.0` and `INFINITY`
  205. #[inline]
  206. fn is_positive(&self) -> bool { *self > 0.0 || (1.0 / *self) == $inf }
  207. /// Returns `true` if the number is negative, including `-0.0` and `NEG_INFINITY`
  208. #[inline]
  209. fn is_negative(&self) -> bool { *self < 0.0 || (1.0 / *self) == $neg_inf }
  210. }
  211. }
  212. )
  213. signed_float_impl!(f32, f32::NAN, f32::INFINITY, f32::NEG_INFINITY,
  214. intrinsics::fabsf32, intrinsics::copysignf32, fdimf)
  215. signed_float_impl!(f64, f64::NAN, f64::INFINITY, f64::NEG_INFINITY,
  216. intrinsics::fabsf64, intrinsics::copysignf64, fdim)
  217. /// A trait for values which cannot be negative
  218. pub trait Unsigned: Num {}
  219. trait_impl!(Unsigned for uint u8 u16 u32 u64)
  220. /// Numbers which have upper and lower bounds
  221. pub trait Bounded {
  222. // FIXME (#5527): These should be associated constants
  223. /// returns the smallest finite number this type can represent
  224. fn min_value() -> Self;
  225. /// returns the largest finite number this type can represent
  226. fn max_value() -> Self;
  227. }
  228. macro_rules! bounded_impl(
  229. ($t:ty, $min:expr, $max:expr) => {
  230. impl Bounded for $t {
  231. #[inline]
  232. fn min_value() -> $t { $min }
  233. #[inline]
  234. fn max_value() -> $t { $max }
  235. }
  236. }
  237. )
  238. bounded_impl!(uint, uint::MIN, uint::MAX)
  239. bounded_impl!(u8, u8::MIN, u8::MAX)
  240. bounded_impl!(u16, u16::MIN, u16::MAX)
  241. bounded_impl!(u32, u32::MIN, u32::MAX)
  242. bounded_impl!(u64, u64::MIN, u64::MAX)
  243. bounded_impl!(int, int::MIN, int::MAX)
  244. bounded_impl!(i8, i8::MIN, i8::MAX)
  245. bounded_impl!(i16, i16::MIN, i16::MAX)
  246. bounded_impl!(i32, i32::MIN, i32::MAX)
  247. bounded_impl!(i64, i64::MIN, i64::MAX)
  248. bounded_impl!(f32, f32::MIN_VALUE, f32::MAX_VALUE)
  249. bounded_impl!(f64, f64::MIN_VALUE, f64::MAX_VALUE)
  250. /// Saturating math operations
  251. pub trait Saturating {
  252. /// Saturating addition operator.
  253. /// Returns a+b, saturating at the numeric bounds instead of overflowing.
  254. fn saturating_add(self, v: Self) -> Self;
  255. /// Saturating subtraction operator.
  256. /// Returns a-b, saturating at the numeric bounds instead of overflowing.
  257. fn saturating_sub(self, v: Self) -> Self;
  258. }
  259. impl<T: CheckedAdd + CheckedSub + Zero + PartialOrd + Bounded> Saturating for T {
  260. #[inline]
  261. fn saturating_add(self, v: T) -> T {
  262. match self.checked_add(&v) {
  263. Some(x) => x,
  264. None => if v >= Zero::zero() {
  265. Bounded::max_value()
  266. } else {
  267. Bounded::min_value()
  268. }
  269. }
  270. }
  271. #[inline]
  272. fn saturating_sub(self, v: T) -> T {
  273. match self.checked_sub(&v) {
  274. Some(x) => x,
  275. None => if v >= Zero::zero() {
  276. Bounded::min_value()
  277. } else {
  278. Bounded::max_value()
  279. }
  280. }
  281. }
  282. }
  283. /// Performs addition that returns `None` instead of wrapping around on overflow.
  284. pub trait CheckedAdd: Add<Self, Self> {
  285. /// Adds two numbers, checking for overflow. If overflow happens, `None` is returned.
  286. ///
  287. /// # Example
  288. ///
  289. /// ```rust
  290. /// use num::CheckedAdd;
  291. /// assert_eq!(5u16.checked_add(&65530), Some(65535));
  292. /// assert_eq!(6u16.checked_add(&65530), None);
  293. /// ```
  294. fn checked_add(&self, v: &Self) -> Option<Self>;
  295. }
  296. macro_rules! checked_impl(
  297. ($trait_name:ident, $method:ident, $t:ty, $op:path) => {
  298. impl $trait_name for $t {
  299. #[inline]
  300. fn $method(&self, v: &$t) -> Option<$t> {
  301. unsafe {
  302. let (x, y) = $op(*self, *v);
  303. if y { None } else { Some(x) }
  304. }
  305. }
  306. }
  307. }
  308. )
  309. macro_rules! checked_cast_impl(
  310. ($trait_name:ident, $method:ident, $t:ty, $cast:ty, $op:path) => {
  311. impl $trait_name for $t {
  312. #[inline]
  313. fn $method(&self, v: &$t) -> Option<$t> {
  314. unsafe {
  315. let (x, y) = $op(*self as $cast, *v as $cast);
  316. if y { None } else { Some(x as $t) }
  317. }
  318. }
  319. }
  320. }
  321. )
  322. #[cfg(target_word_size = "32")]
  323. checked_cast_impl!(CheckedAdd, checked_add, uint, u32, intrinsics::u32_add_with_overflow)
  324. #[cfg(target_word_size = "64")]
  325. checked_cast_impl!(CheckedAdd, checked_add, uint, u64, intrinsics::u64_add_with_overflow)
  326. checked_impl!(CheckedAdd, checked_add, u8, intrinsics::u8_add_with_overflow)
  327. checked_impl!(CheckedAdd, checked_add, u16, intrinsics::u16_add_with_overflow)
  328. checked_impl!(CheckedAdd, checked_add, u32, intrinsics::u32_add_with_overflow)
  329. checked_impl!(CheckedAdd, checked_add, u64, intrinsics::u64_add_with_overflow)
  330. #[cfg(target_word_size = "32")]
  331. checked_cast_impl!(CheckedAdd, checked_add, int, i32, intrinsics::i32_add_with_overflow)
  332. #[cfg(target_word_size = "64")]
  333. checked_cast_impl!(CheckedAdd, checked_add, int, i64, intrinsics::i64_add_with_overflow)
  334. checked_impl!(CheckedAdd, checked_add, i8, intrinsics::i8_add_with_overflow)
  335. checked_impl!(CheckedAdd, checked_add, i16, intrinsics::i16_add_with_overflow)
  336. checked_impl!(CheckedAdd, checked_add, i32, intrinsics::i32_add_with_overflow)
  337. checked_impl!(CheckedAdd, checked_add, i64, intrinsics::i64_add_with_overflow)
  338. /// Performs subtraction that returns `None` instead of wrapping around on underflow.
  339. pub trait CheckedSub: Sub<Self, Self> {
  340. /// Subtracts two numbers, checking for underflow. If underflow happens, `None` is returned.
  341. ///
  342. /// # Example
  343. ///
  344. /// ```rust
  345. /// use num::CheckedSub;
  346. /// assert_eq!((-127i8).checked_sub(&1), Some(-128));
  347. /// assert_eq!((-128i8).checked_sub(&1), None);
  348. /// ```
  349. fn checked_sub(&self, v: &Self) -> Option<Self>;
  350. }
  351. #[cfg(target_word_size = "32")]
  352. checked_cast_impl!(CheckedSub, checked_sub, uint, u32, intrinsics::u32_sub_with_overflow)
  353. #[cfg(target_word_size = "64")]
  354. checked_cast_impl!(CheckedSub, checked_sub, uint, u64, intrinsics::u64_sub_with_overflow)
  355. checked_impl!(CheckedSub, checked_sub, u8, intrinsics::u8_sub_with_overflow)
  356. checked_impl!(CheckedSub, checked_sub, u16, intrinsics::u16_sub_with_overflow)
  357. checked_impl!(CheckedSub, checked_sub, u32, intrinsics::u32_sub_with_overflow)
  358. checked_impl!(CheckedSub, checked_sub, u64, intrinsics::u64_sub_with_overflow)
  359. #[cfg(target_word_size = "32")]
  360. checked_cast_impl!(CheckedSub, checked_sub, int, i32, intrinsics::i32_sub_with_overflow)
  361. #[cfg(target_word_size = "64")]
  362. checked_cast_impl!(CheckedSub, checked_sub, int, i64, intrinsics::i64_sub_with_overflow)
  363. checked_impl!(CheckedSub, checked_sub, i8, intrinsics::i8_sub_with_overflow)
  364. checked_impl!(CheckedSub, checked_sub, i16, intrinsics::i16_sub_with_overflow)
  365. checked_impl!(CheckedSub, checked_sub, i32, intrinsics::i32_sub_with_overflow)
  366. checked_impl!(CheckedSub, checked_sub, i64, intrinsics::i64_sub_with_overflow)
  367. /// Performs multiplication that returns `None` instead of wrapping around on underflow or
  368. /// overflow.
  369. pub trait CheckedMul: Mul<Self, Self> {
  370. /// Multiplies two numbers, checking for underflow or overflow. If underflow or overflow
  371. /// happens, `None` is returned.
  372. ///
  373. /// # Example
  374. ///
  375. /// ```rust
  376. /// use num::CheckedMul;
  377. /// assert_eq!(5u8.checked_mul(&51), Some(255));
  378. /// assert_eq!(5u8.checked_mul(&52), None);
  379. /// ```
  380. fn checked_mul(&self, v: &Self) -> Option<Self>;
  381. }
  382. #[cfg(target_word_size = "32")]
  383. checked_cast_impl!(CheckedMul, checked_mul, uint, u32, intrinsics::u32_mul_with_overflow)
  384. #[cfg(target_word_size = "64")]
  385. checked_cast_impl!(CheckedMul, checked_mul, uint, u64, intrinsics::u64_mul_with_overflow)
  386. checked_impl!(CheckedMul, checked_mul, u8, intrinsics::u8_mul_with_overflow)
  387. checked_impl!(CheckedMul, checked_mul, u16, intrinsics::u16_mul_with_overflow)
  388. checked_impl!(CheckedMul, checked_mul, u32, intrinsics::u32_mul_with_overflow)
  389. checked_impl!(CheckedMul, checked_mul, u64, intrinsics::u64_mul_with_overflow)
  390. #[cfg(target_word_size = "32")]
  391. checked_cast_impl!(CheckedMul, checked_mul, int, i32, intrinsics::i32_mul_with_overflow)
  392. #[cfg(target_word_size = "64")]
  393. checked_cast_impl!(CheckedMul, checked_mul, int, i64, intrinsics::i64_mul_with_overflow)
  394. checked_impl!(CheckedMul, checked_mul, i8, intrinsics::i8_mul_with_overflow)
  395. checked_impl!(CheckedMul, checked_mul, i16, intrinsics::i16_mul_with_overflow)
  396. checked_impl!(CheckedMul, checked_mul, i32, intrinsics::i32_mul_with_overflow)
  397. checked_impl!(CheckedMul, checked_mul, i64, intrinsics::i64_mul_with_overflow)
  398. /// Performs division that returns `None` instead of panicking on division by zero and instead of
  399. /// wrapping around on underflow and overflow.
  400. pub trait CheckedDiv: Div<Self, Self> {
  401. /// Divides two numbers, checking for underflow, overflow and division by zero. If any of that
  402. /// happens, `None` is returned.
  403. ///
  404. /// # Example
  405. ///
  406. /// ```rust
  407. /// use num::CheckedDiv;
  408. /// assert_eq!((-127i8).checked_div(&-1), Some(127));
  409. /// assert_eq!((-128i8).checked_div(&-1), None);
  410. /// assert_eq!((1i8).checked_div(&0), None);
  411. /// ```
  412. fn checked_div(&self, v: &Self) -> Option<Self>;
  413. }
  414. macro_rules! checkeddiv_int_impl(
  415. ($t:ty, $min:expr) => {
  416. impl CheckedDiv for $t {
  417. #[inline]
  418. fn checked_div(&self, v: &$t) -> Option<$t> {
  419. if *v == 0 || (*self == $min && *v == -1) {
  420. None
  421. } else {
  422. Some(*self / *v)
  423. }
  424. }
  425. }
  426. }
  427. )
  428. checkeddiv_int_impl!(int, int::MIN)
  429. checkeddiv_int_impl!(i8, i8::MIN)
  430. checkeddiv_int_impl!(i16, i16::MIN)
  431. checkeddiv_int_impl!(i32, i32::MIN)
  432. checkeddiv_int_impl!(i64, i64::MIN)
  433. macro_rules! checkeddiv_uint_impl(
  434. ($($t:ty)*) => ($(
  435. impl CheckedDiv for $t {
  436. #[inline]
  437. fn checked_div(&self, v: &$t) -> Option<$t> {
  438. if *v == 0 {
  439. None
  440. } else {
  441. Some(*self / *v)
  442. }
  443. }
  444. }
  445. )*)
  446. )
  447. checkeddiv_uint_impl!(uint u8 u16 u32 u64)