/rust/registry/src/index.crates.io-6f17d22bba15001f/num-traits-0.2.15/src/sign.rs
Line | Count | Source (jump to first uncovered line) |
1 | | use core::num::Wrapping; |
2 | | use core::ops::Neg; |
3 | | |
4 | | use float::FloatCore; |
5 | | use Num; |
6 | | |
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. |
10 | | /// |
11 | | /// For `f32` and `f64`, `NaN` will be returned if the number is `NaN`. |
12 | | /// |
13 | | /// For signed integers, `::MIN` will be returned if the number is `::MIN`. |
14 | | fn abs(&self) -> Self; |
15 | | |
16 | | /// The positive difference of two numbers. |
17 | | /// |
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; |
21 | | |
22 | | /// Returns the sign of the number. |
23 | | /// |
24 | | /// For `f32` and `f64`: |
25 | | /// |
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` |
29 | | /// |
30 | | /// For signed integers: |
31 | | /// |
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; |
36 | | |
37 | | /// Returns true if the number is positive and false if the number is zero or negative. |
38 | | fn is_positive(&self) -> bool; |
39 | | |
40 | | /// Returns true if the number is negative and false if the number is zero or positive. |
41 | | fn is_negative(&self) -> bool; |
42 | | } |
43 | | |
44 | | macro_rules! signed_impl { |
45 | | ($($t:ty)*) => ($( |
46 | | impl Signed for $t { |
47 | | #[inline] |
48 | 0 | fn abs(&self) -> $t { |
49 | 0 | if self.is_negative() { -*self } else { *self } |
50 | 0 | } Unexecuted instantiation: <isize as num_traits::sign::Signed>::abs Unexecuted instantiation: <i8 as num_traits::sign::Signed>::abs Unexecuted instantiation: <i16 as num_traits::sign::Signed>::abs Unexecuted instantiation: <i32 as num_traits::sign::Signed>::abs Unexecuted instantiation: <i64 as num_traits::sign::Signed>::abs Unexecuted instantiation: <i128 as num_traits::sign::Signed>::abs |
51 | | |
52 | | #[inline] |
53 | 0 | fn abs_sub(&self, other: &$t) -> $t { |
54 | 0 | if *self <= *other { 0 } else { *self - *other } |
55 | 0 | } Unexecuted instantiation: <isize as num_traits::sign::Signed>::abs_sub Unexecuted instantiation: <i8 as num_traits::sign::Signed>::abs_sub Unexecuted instantiation: <i16 as num_traits::sign::Signed>::abs_sub Unexecuted instantiation: <i32 as num_traits::sign::Signed>::abs_sub Unexecuted instantiation: <i64 as num_traits::sign::Signed>::abs_sub Unexecuted instantiation: <i128 as num_traits::sign::Signed>::abs_sub |
56 | | |
57 | | #[inline] |
58 | 0 | fn signum(&self) -> $t { |
59 | 0 | match *self { |
60 | 0 | n if n > 0 => 1, |
61 | 0 | 0 => 0, |
62 | 0 | _ => -1, |
63 | | } |
64 | 0 | } Unexecuted instantiation: <isize as num_traits::sign::Signed>::signum Unexecuted instantiation: <i8 as num_traits::sign::Signed>::signum Unexecuted instantiation: <i16 as num_traits::sign::Signed>::signum Unexecuted instantiation: <i32 as num_traits::sign::Signed>::signum Unexecuted instantiation: <i64 as num_traits::sign::Signed>::signum Unexecuted instantiation: <i128 as num_traits::sign::Signed>::signum |
65 | | |
66 | | #[inline] |
67 | 0 | fn is_positive(&self) -> bool { *self > 0 } Unexecuted instantiation: <isize as num_traits::sign::Signed>::is_positive Unexecuted instantiation: <i8 as num_traits::sign::Signed>::is_positive Unexecuted instantiation: <i16 as num_traits::sign::Signed>::is_positive Unexecuted instantiation: <i32 as num_traits::sign::Signed>::is_positive Unexecuted instantiation: <i64 as num_traits::sign::Signed>::is_positive Unexecuted instantiation: <i128 as num_traits::sign::Signed>::is_positive |
68 | | |
69 | | #[inline] |
70 | 0 | fn is_negative(&self) -> bool { *self < 0 } Unexecuted instantiation: <isize as num_traits::sign::Signed>::is_negative Unexecuted instantiation: <i8 as num_traits::sign::Signed>::is_negative Unexecuted instantiation: <i16 as num_traits::sign::Signed>::is_negative Unexecuted instantiation: <i32 as num_traits::sign::Signed>::is_negative Unexecuted instantiation: <i64 as num_traits::sign::Signed>::is_negative Unexecuted instantiation: <i128 as num_traits::sign::Signed>::is_negative |
71 | | } |
72 | | )*) |
73 | | } |
74 | | |
75 | | signed_impl!(isize i8 i16 i32 i64); |
76 | | |
77 | | #[cfg(has_i128)] |
78 | | signed_impl!(i128); |
79 | | |
80 | | impl<T: Signed> Signed for Wrapping<T> |
81 | | where |
82 | | Wrapping<T>: Num + Neg<Output = Wrapping<T>>, |
83 | | { |
84 | | #[inline] |
85 | 0 | fn abs(&self) -> Self { |
86 | 0 | Wrapping(self.0.abs()) |
87 | 0 | } |
88 | | |
89 | | #[inline] |
90 | 0 | fn abs_sub(&self, other: &Self) -> Self { |
91 | 0 | Wrapping(self.0.abs_sub(&other.0)) |
92 | 0 | } |
93 | | |
94 | | #[inline] |
95 | 0 | fn signum(&self) -> Self { |
96 | 0 | Wrapping(self.0.signum()) |
97 | 0 | } |
98 | | |
99 | | #[inline] |
100 | 0 | fn is_positive(&self) -> bool { |
101 | 0 | self.0.is_positive() |
102 | 0 | } |
103 | | |
104 | | #[inline] |
105 | 0 | fn is_negative(&self) -> bool { |
106 | 0 | self.0.is_negative() |
107 | 0 | } |
108 | | } |
109 | | |
110 | | macro_rules! signed_float_impl { |
111 | | ($t:ty) => { |
112 | | impl Signed for $t { |
113 | | /// Computes the absolute value. Returns `NAN` if the number is `NAN`. |
114 | | #[inline] |
115 | 0 | fn abs(&self) -> $t { |
116 | 0 | FloatCore::abs(*self) |
117 | 0 | } Unexecuted instantiation: <f32 as num_traits::sign::Signed>::abs Unexecuted instantiation: <f64 as num_traits::sign::Signed>::abs |
118 | | |
119 | | /// The positive difference of two numbers. Returns `0.0` if the number is |
120 | | /// less than or equal to `other`, otherwise the difference between`self` |
121 | | /// and `other` is returned. |
122 | | #[inline] |
123 | 0 | fn abs_sub(&self, other: &$t) -> $t { |
124 | 0 | if *self <= *other { |
125 | 0 | 0. |
126 | | } else { |
127 | 0 | *self - *other |
128 | | } |
129 | 0 | } Unexecuted instantiation: <f32 as num_traits::sign::Signed>::abs_sub Unexecuted instantiation: <f64 as num_traits::sign::Signed>::abs_sub |
130 | | |
131 | | /// # Returns |
132 | | /// |
133 | | /// - `1.0` if the number is positive, `+0.0` or `INFINITY` |
134 | | /// - `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY` |
135 | | /// - `NAN` if the number is NaN |
136 | | #[inline] |
137 | 0 | fn signum(&self) -> $t { |
138 | 0 | FloatCore::signum(*self) |
139 | 0 | } Unexecuted instantiation: <f32 as num_traits::sign::Signed>::signum Unexecuted instantiation: <f64 as num_traits::sign::Signed>::signum |
140 | | |
141 | | /// Returns `true` if the number is positive, including `+0.0` and `INFINITY` |
142 | | #[inline] |
143 | 0 | fn is_positive(&self) -> bool { |
144 | 0 | FloatCore::is_sign_positive(*self) |
145 | 0 | } Unexecuted instantiation: <f32 as num_traits::sign::Signed>::is_positive Unexecuted instantiation: <f64 as num_traits::sign::Signed>::is_positive |
146 | | |
147 | | /// Returns `true` if the number is negative, including `-0.0` and `NEG_INFINITY` |
148 | | #[inline] |
149 | 0 | fn is_negative(&self) -> bool { |
150 | 0 | FloatCore::is_sign_negative(*self) |
151 | 0 | } Unexecuted instantiation: <f32 as num_traits::sign::Signed>::is_negative Unexecuted instantiation: <f64 as num_traits::sign::Signed>::is_negative |
152 | | } |
153 | | }; |
154 | | } |
155 | | |
156 | | signed_float_impl!(f32); |
157 | | signed_float_impl!(f64); |
158 | | |
159 | | /// Computes the absolute value. |
160 | | /// |
161 | | /// For `f32` and `f64`, `NaN` will be returned if the number is `NaN` |
162 | | /// |
163 | | /// For signed integers, `::MIN` will be returned if the number is `::MIN`. |
164 | | #[inline(always)] |
165 | 0 | pub fn abs<T: Signed>(value: T) -> T { |
166 | 0 | value.abs() |
167 | 0 | } |
168 | | |
169 | | /// The positive difference of two numbers. |
170 | | /// |
171 | | /// Returns zero if `x` is less than or equal to `y`, otherwise the difference |
172 | | /// between `x` and `y` is returned. |
173 | | #[inline(always)] |
174 | 0 | pub fn abs_sub<T: Signed>(x: T, y: T) -> T { |
175 | 0 | x.abs_sub(&y) |
176 | 0 | } |
177 | | |
178 | | /// Returns the sign of the number. |
179 | | /// |
180 | | /// For `f32` and `f64`: |
181 | | /// |
182 | | /// * `1.0` if the number is positive, `+0.0` or `INFINITY` |
183 | | /// * `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY` |
184 | | /// * `NaN` if the number is `NaN` |
185 | | /// |
186 | | /// For signed integers: |
187 | | /// |
188 | | /// * `0` if the number is zero |
189 | | /// * `1` if the number is positive |
190 | | /// * `-1` if the number is negative |
191 | | #[inline(always)] |
192 | 0 | pub fn signum<T: Signed>(value: T) -> T { |
193 | 0 | value.signum() |
194 | 0 | } |
195 | | |
196 | | /// A trait for values which cannot be negative |
197 | | pub trait Unsigned: Num {} |
198 | | |
199 | | macro_rules! empty_trait_impl { |
200 | | ($name:ident for $($t:ty)*) => ($( |
201 | | impl $name for $t {} |
202 | | )*) |
203 | | } |
204 | | |
205 | | empty_trait_impl!(Unsigned for usize u8 u16 u32 u64); |
206 | | #[cfg(has_i128)] |
207 | | empty_trait_impl!(Unsigned for u128); |
208 | | |
209 | | impl<T: Unsigned> Unsigned for Wrapping<T> where Wrapping<T>: Num {} |
210 | | |
211 | | #[test] |
212 | | fn unsigned_wrapping_is_unsigned() { |
213 | | fn require_unsigned<T: Unsigned>(_: &T) {} |
214 | | require_unsigned(&Wrapping(42_u32)); |
215 | | } |
216 | | |
217 | | // Commenting this out since it doesn't compile on Rust 1.8, |
218 | | // because on this version Wrapping doesn't implement Neg and therefore can't |
219 | | // implement Signed. |
220 | | // #[test] |
221 | | // fn signed_wrapping_is_signed() { |
222 | | // fn require_signed<T: Signed>(_: &T) {} |
223 | | // require_signed(&Wrapping(-42)); |
224 | | // } |