2 use core
::num
::Wrapping
;
7 /// Useful functions for signed numbers (i.e. numbers that can be negative).
8 pub trait Signed
: Sized
+ Num
+ Neg
<Output
= Self> {
9 /// Computes the absolute value.
11 /// For `f32` and `f64`, `NaN` will be returned if the number is `NaN`.
13 /// For signed integers, `::MIN` will be returned if the number is `::MIN`.
14 fn abs(&self) -> Self;
16 /// The positive difference of two numbers.
18 /// Returns `zero` if the number is less than or equal to `other`, otherwise the difference
19 /// between `self` and `other` is returned.
20 fn abs_sub(&self, other
: &Self) -> Self;
22 /// Returns the sign of the number.
24 /// For `f32` and `f64`:
26 /// * `1.0` if the number is positive, `+0.0` or `INFINITY`
27 /// * `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY`
28 /// * `NaN` if the number is `NaN`
30 /// For signed integers:
32 /// * `0` if the number is zero
33 /// * `1` if the number is positive
34 /// * `-1` if the number is negative
35 fn signum(&self) -> Self;
37 /// Returns true if the number is positive and false if the number is zero or negative.
38 fn is_positive(&self) -> bool
;
40 /// Returns true if the number is negative and false if the number is zero or positive.
41 fn is_negative(&self) -> bool
;
44 macro_rules
! signed_impl
{
49 if self.is_negative() { -*self }
else { *self }
53 fn abs_sub(&self, other
: &$t
) -> $t
{
54 if *self <= *other { 0 }
else { *self - *other }
58 fn signum(&self) -> $t
{
67 fn is_positive(&self) -> bool { *self > 0 }
70 fn is_negative(&self) -> bool { *self < 0 }
75 signed_impl
!(isize i8 i16 i32 i64);
77 impl<T
: Signed
> Signed
for Wrapping
<T
> where Wrapping
<T
>: Num
+ Neg
<Output
=Wrapping
<T
>>
80 fn abs(&self) -> Self {
81 Wrapping(self.0.abs())
85 fn abs_sub(&self, other
: &Self) -> Self {
86 Wrapping(self.0.abs_sub(&other
.0))
90 fn signum(&self) -> Self {
91 Wrapping(self.0.signum())
95 fn is_positive(&self) -> bool { self.0.is_positive() }
98 fn is_negative(&self) -> bool { self.0.is_negative() }
101 macro_rules
! signed_float_impl
{
104 /// Computes the absolute value. Returns `NAN` if the number is `NAN`.
106 fn abs(&self) -> $t
{
107 FloatCore
::abs(*self)
110 /// The positive difference of two numbers. Returns `0.0` if the number is
111 /// less than or equal to `other`, otherwise the difference between`self`
112 /// and `other` is returned.
114 fn abs_sub(&self, other
: &$t
) -> $t
{
115 if *self <= *other { 0. }
else { *self - *other }
120 /// - `1.0` if the number is positive, `+0.0` or `INFINITY`
121 /// - `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY`
122 /// - `NAN` if the number is NaN
124 fn signum(&self) -> $t
{
125 FloatCore
::signum(*self)
128 /// Returns `true` if the number is positive, including `+0.0` and `INFINITY`
130 fn is_positive(&self) -> bool { FloatCore::is_sign_positive(*self) }
132 /// Returns `true` if the number is negative, including `-0.0` and `NEG_INFINITY`
134 fn is_negative(&self) -> bool { FloatCore::is_sign_negative(*self) }
139 signed_float_impl
!(f32);
140 signed_float_impl
!(f64);
142 /// Computes the absolute value.
144 /// For `f32` and `f64`, `NaN` will be returned if the number is `NaN`
146 /// For signed integers, `::MIN` will be returned if the number is `::MIN`.
148 pub fn abs
<T
: Signed
>(value
: T
) -> T
{
152 /// The positive difference of two numbers.
154 /// Returns zero if `x` is less than or equal to `y`, otherwise the difference
155 /// between `x` and `y` is returned.
157 pub fn abs_sub
<T
: Signed
>(x
: T
, y
: T
) -> T
{
161 /// Returns the sign of the number.
163 /// For `f32` and `f64`:
165 /// * `1.0` if the number is positive, `+0.0` or `INFINITY`
166 /// * `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY`
167 /// * `NaN` if the number is `NaN`
169 /// For signed integers:
171 /// * `0` if the number is zero
172 /// * `1` if the number is positive
173 /// * `-1` if the number is negative
174 #[inline(always)] pub fn signum<T: Signed>(value: T) -> T { value.signum() }
176 /// A trait for values which cannot be negative
177 pub trait Unsigned
: Num {}
179 macro_rules
! empty_trait_impl
{
180 ($name
:ident
for $
($t
:ty
)*) => ($
(
185 empty_trait_impl
!(Unsigned
for usize u8 u16 u32 u64);
187 impl<T
: Unsigned
> Unsigned
for Wrapping
<T
> where Wrapping
<T
>: Num {}
190 fn unsigned_wrapping_is_unsigned() {
191 fn require_unsigned
<T
: Unsigned
>(_
: &T
) {}
192 require_unsigned(&Wrapping(42_u32));
195 // Commenting this out since it doesn't compile on Rust 1.8,
196 // because on this version Wrapping doesn't implement Neg and therefore can't
199 fn signed_wrapping_is_signed() {
200 fn require_signed<T: Signed>(_: &T) {}
201 require_signed(&Wrapping(-42));