sign.rs 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. use core::ops::Neg;
  2. use core::num::Wrapping;
  3. use Num;
  4. use float::FloatCore;
  5. /// Useful functions for signed numbers (i.e. numbers that can be negative).
  6. pub trait Signed: Sized + Num + Neg<Output = Self> {
  7. /// Computes the absolute value.
  8. ///
  9. /// For `f32` and `f64`, `NaN` will be returned if the number is `NaN`.
  10. ///
  11. /// For signed integers, `::MIN` will be returned if the number is `::MIN`.
  12. fn abs(&self) -> Self;
  13. /// The positive difference of two numbers.
  14. ///
  15. /// Returns `zero` if the number is less than or equal to `other`, otherwise the difference
  16. /// between `self` and `other` is returned.
  17. fn abs_sub(&self, other: &Self) -> Self;
  18. /// Returns the sign of the number.
  19. ///
  20. /// For `f32` and `f64`:
  21. ///
  22. /// * `1.0` if the number is positive, `+0.0` or `INFINITY`
  23. /// * `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY`
  24. /// * `NaN` if the number is `NaN`
  25. ///
  26. /// For signed integers:
  27. ///
  28. /// * `0` if the number is zero
  29. /// * `1` if the number is positive
  30. /// * `-1` if the number is negative
  31. fn signum(&self) -> Self;
  32. /// Returns true if the number is positive and false if the number is zero or negative.
  33. fn is_positive(&self) -> bool;
  34. /// Returns true if the number is negative and false if the number is zero or positive.
  35. fn is_negative(&self) -> bool;
  36. }
  37. macro_rules! signed_impl {
  38. ($($t:ty)*) => ($(
  39. impl Signed for $t {
  40. #[inline]
  41. fn abs(&self) -> $t {
  42. if self.is_negative() { -*self } else { *self }
  43. }
  44. #[inline]
  45. fn abs_sub(&self, other: &$t) -> $t {
  46. if *self <= *other { 0 } else { *self - *other }
  47. }
  48. #[inline]
  49. fn signum(&self) -> $t {
  50. match *self {
  51. n if n > 0 => 1,
  52. 0 => 0,
  53. _ => -1,
  54. }
  55. }
  56. #[inline]
  57. fn is_positive(&self) -> bool { *self > 0 }
  58. #[inline]
  59. fn is_negative(&self) -> bool { *self < 0 }
  60. }
  61. )*)
  62. }
  63. signed_impl!(isize i8 i16 i32 i64);
  64. #[cfg(has_i128)]
  65. signed_impl!(i128);
  66. impl<T: Signed> Signed for Wrapping<T> where Wrapping<T>: Num + Neg<Output=Wrapping<T>>
  67. {
  68. #[inline]
  69. fn abs(&self) -> Self {
  70. Wrapping(self.0.abs())
  71. }
  72. #[inline]
  73. fn abs_sub(&self, other: &Self) -> Self {
  74. Wrapping(self.0.abs_sub(&other.0))
  75. }
  76. #[inline]
  77. fn signum(&self) -> Self {
  78. Wrapping(self.0.signum())
  79. }
  80. #[inline]
  81. fn is_positive(&self) -> bool { self.0.is_positive() }
  82. #[inline]
  83. fn is_negative(&self) -> bool { self.0.is_negative() }
  84. }
  85. macro_rules! signed_float_impl {
  86. ($t:ty) => {
  87. impl Signed for $t {
  88. /// Computes the absolute value. Returns `NAN` if the number is `NAN`.
  89. #[inline]
  90. fn abs(&self) -> $t {
  91. FloatCore::abs(*self)
  92. }
  93. /// The positive difference of two numbers. Returns `0.0` if the number is
  94. /// less than or equal to `other`, otherwise the difference between`self`
  95. /// and `other` is returned.
  96. #[inline]
  97. fn abs_sub(&self, other: &$t) -> $t {
  98. if *self <= *other { 0. } else { *self - *other }
  99. }
  100. /// # Returns
  101. ///
  102. /// - `1.0` if the number is positive, `+0.0` or `INFINITY`
  103. /// - `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY`
  104. /// - `NAN` if the number is NaN
  105. #[inline]
  106. fn signum(&self) -> $t {
  107. FloatCore::signum(*self)
  108. }
  109. /// Returns `true` if the number is positive, including `+0.0` and `INFINITY`
  110. #[inline]
  111. fn is_positive(&self) -> bool { FloatCore::is_sign_positive(*self) }
  112. /// Returns `true` if the number is negative, including `-0.0` and `NEG_INFINITY`
  113. #[inline]
  114. fn is_negative(&self) -> bool { FloatCore::is_sign_negative(*self) }
  115. }
  116. }
  117. }
  118. signed_float_impl!(f32);
  119. signed_float_impl!(f64);
  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. #[inline(always)]
  126. pub fn abs<T: Signed>(value: T) -> T {
  127. value.abs()
  128. }
  129. /// The positive difference of two numbers.
  130. ///
  131. /// Returns zero if `x` is less than or equal to `y`, otherwise the difference
  132. /// between `x` and `y` is returned.
  133. #[inline(always)]
  134. pub fn abs_sub<T: Signed>(x: T, y: T) -> T {
  135. x.abs_sub(&y)
  136. }
  137. /// Returns the sign of the number.
  138. ///
  139. /// For `f32` and `f64`:
  140. ///
  141. /// * `1.0` if the number is positive, `+0.0` or `INFINITY`
  142. /// * `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY`
  143. /// * `NaN` if the number is `NaN`
  144. ///
  145. /// For signed integers:
  146. ///
  147. /// * `0` if the number is zero
  148. /// * `1` if the number is positive
  149. /// * `-1` if the number is negative
  150. #[inline(always)] pub fn signum<T: Signed>(value: T) -> T { value.signum() }
  151. /// A trait for values which cannot be negative
  152. pub trait Unsigned: Num {}
  153. macro_rules! empty_trait_impl {
  154. ($name:ident for $($t:ty)*) => ($(
  155. impl $name for $t {}
  156. )*)
  157. }
  158. empty_trait_impl!(Unsigned for usize u8 u16 u32 u64);
  159. #[cfg(has_i128)]
  160. empty_trait_impl!(Unsigned for u128);
  161. impl<T: Unsigned> Unsigned for Wrapping<T> where Wrapping<T>: Num {}
  162. #[test]
  163. fn unsigned_wrapping_is_unsigned() {
  164. fn require_unsigned<T: Unsigned>(_: &T) {}
  165. require_unsigned(&Wrapping(42_u32));
  166. }
  167. /*
  168. // Commenting this out since it doesn't compile on Rust 1.8,
  169. // because on this version Wrapping doesn't implement Neg and therefore can't
  170. // implement Signed.
  171. #[test]
  172. fn signed_wrapping_is_signed() {
  173. fn require_signed<T: Signed>(_: &T) {}
  174. require_signed(&Wrapping(-42));
  175. }
  176. */