/src/rust-lexical/lexical-util/src/num.rs
Line | Count | Source |
1 | | //! Utilities for Rust numbers. |
2 | | //! |
3 | | //! These traits define useful properties, methods, associated |
4 | | //! types, and trait bounds, and conversions for working with |
5 | | //! numbers in generic code. |
6 | | |
7 | | use core::{fmt, mem, ops}; |
8 | | |
9 | | #[cfg(feature = "f16")] |
10 | | use crate::bf16::bf16; |
11 | | #[cfg(feature = "f16")] |
12 | | use crate::f16::f16; |
13 | | #[cfg(all(not(feature = "std"), any(feature = "parse-floats", feature = "write-floats")))] |
14 | | use crate::libm; |
15 | | |
16 | | // AS PRIMITIVE |
17 | | // ------------ |
18 | | |
19 | | /// Type that can be converted to [`primitive`] values with `as`. |
20 | | /// |
21 | | /// [`primitive`]: https://doc.rust-lang.org/rust-by-example/primitives.html |
22 | | pub trait AsPrimitive: Copy + PartialEq + PartialOrd + Send + Sync + Sized { |
23 | | /// Convert the value to a [`u8`], as if by `value as u8`. |
24 | | fn as_u8(self) -> u8; |
25 | | |
26 | | /// Convert the value to a [`u16`], as if by `value as u16`. |
27 | | fn as_u16(self) -> u16; |
28 | | |
29 | | /// Convert the value to a [`u32`], as if by `value as u32`. |
30 | | fn as_u32(self) -> u32; |
31 | | |
32 | | /// Convert the value to a [`u64`], as if by `value as u64`. |
33 | | fn as_u64(self) -> u64; |
34 | | |
35 | | /// Convert the value to a [`u128`], as if by `value as u128`. |
36 | | fn as_u128(self) -> u128; |
37 | | |
38 | | /// Convert the value to a [`usize`], as if by `value as usize`. |
39 | | fn as_usize(self) -> usize; |
40 | | |
41 | | /// Convert the value to an [`i8`], as if by `value as i8`. |
42 | | fn as_i8(self) -> i8; |
43 | | |
44 | | /// Convert the value to an [`i16`], as if by `value as i16`. |
45 | | fn as_i16(self) -> i16; |
46 | | |
47 | | /// Convert the value to an [`i32`], as if by `value as i32`. |
48 | | fn as_i32(self) -> i32; |
49 | | |
50 | | /// Convert the value to an [`i64`], as if by `value as i64`. |
51 | | fn as_i64(self) -> i64; |
52 | | |
53 | | /// Convert the value to an [`i128`], as if by `value as i128`. |
54 | | fn as_i128(self) -> i128; |
55 | | |
56 | | /// Convert the value to an [`isize`], as if by `value as isize`. |
57 | | fn as_isize(self) -> isize; |
58 | | |
59 | | /// Convert the value to an [`f32`], as if by `value as f32`. |
60 | | fn as_f32(self) -> f32; |
61 | | |
62 | | /// Convert the value to an [`f64`], as if by `value as f64`. |
63 | | fn as_f64(self) -> f64; |
64 | | |
65 | | /// Convert the value from a [`u32`], as if by `value as _`. |
66 | | fn from_u32(value: u32) -> Self; |
67 | | |
68 | | /// Convert the value from a [`u64`], as if by `value as _`. |
69 | | fn from_u64(value: u64) -> Self; |
70 | | |
71 | | /// Convert the value to an [`struct@f16`], identical to `value as f16` |
72 | | /// if [`struct@f16`] was a primitive type. |
73 | | #[cfg(feature = "f16")] |
74 | | fn as_f16(self) -> f16; |
75 | | |
76 | | /// Convert the value to an [`struct@bf16`], identical to `value as bf16` |
77 | | /// if [`struct@bf16`] was a primitive type. |
78 | | #[cfg(feature = "f16")] |
79 | | fn as_bf16(self) -> bf16; |
80 | | } |
81 | | |
82 | | macro_rules! as_primitive { |
83 | | ($($t:ty)*) => ($( |
84 | | impl AsPrimitive for $t { |
85 | | #[inline(always)] |
86 | 39 | fn as_u8(self) -> u8 { |
87 | 0 | self as u8 |
88 | 39 | } <i8 as lexical_util::num::AsPrimitive>::as_u8 Line | Count | Source | 86 | 39 | fn as_u8(self) -> u8 { | 87 | 39 | self as u8 | 88 | 39 | } |
Unexecuted instantiation: <u32 as lexical_util::num::AsPrimitive>::as_u8 Unexecuted instantiation: <u8 as lexical_util::num::AsPrimitive>::as_u8 Unexecuted instantiation: <u64 as lexical_util::num::AsPrimitive>::as_u8 |
89 | | |
90 | | #[inline(always)] |
91 | 41 | fn as_u16(self) -> u16 { |
92 | 1 | self as u16 |
93 | 41 | } <i16 as lexical_util::num::AsPrimitive>::as_u16 Line | Count | Source | 91 | 38 | fn as_u16(self) -> u16 { | 92 | 38 | self as u16 | 93 | 38 | } |
<u32 as lexical_util::num::AsPrimitive>::as_u16 Line | Count | Source | 91 | 2 | fn as_u16(self) -> u16 { | 92 | 2 | self as u16 | 93 | 2 | } |
<u16 as lexical_util::num::AsPrimitive>::as_u16 Line | Count | Source | 91 | 1 | fn as_u16(self) -> u16 { | 92 | 1 | self as u16 | 93 | 1 | } |
Unexecuted instantiation: <u64 as lexical_util::num::AsPrimitive>::as_u16 |
94 | | |
95 | | #[inline(always)] |
96 | 2.95k | fn as_u32(self) -> u32 { |
97 | 23 | self as u32 |
98 | 2.95k | } <u32 as lexical_util::num::AsPrimitive>::as_u32 Line | Count | Source | 96 | 23 | fn as_u32(self) -> u32 { | 97 | 23 | self as u32 | 98 | 23 | } |
<u64 as lexical_util::num::AsPrimitive>::as_u32 Line | Count | Source | 96 | 2.89k | fn as_u32(self) -> u32 { | 97 | 2.89k | self as u32 | 98 | 2.89k | } |
<i32 as lexical_util::num::AsPrimitive>::as_u32 Line | Count | Source | 96 | 37 | fn as_u32(self) -> u32 { | 97 | 37 | self as u32 | 98 | 37 | } |
|
99 | | |
100 | | #[inline(always)] |
101 | 9.08M | fn as_u64(self) -> u64 { |
102 | 9.07M | self as u64 |
103 | 9.08M | } <u32 as lexical_util::num::AsPrimitive>::as_u64 Line | Count | Source | 101 | 7.17k | fn as_u64(self) -> u64 { | 102 | 7.17k | self as u64 | 103 | 7.17k | } |
<u64 as lexical_util::num::AsPrimitive>::as_u64 Line | Count | Source | 101 | 9.07M | fn as_u64(self) -> u64 { | 102 | 9.07M | self as u64 | 103 | 9.07M | } |
<isize as lexical_util::num::AsPrimitive>::as_u64 Line | Count | Source | 101 | 40 | fn as_u64(self) -> u64 { | 102 | 40 | self as u64 | 103 | 40 | } |
<i64 as lexical_util::num::AsPrimitive>::as_u64 Line | Count | Source | 101 | 31 | fn as_u64(self) -> u64 { | 102 | 31 | self as u64 | 103 | 31 | } |
|
104 | | |
105 | | #[inline(always)] |
106 | 1.50k | fn as_u128(self) -> u128 { |
107 | 0 | self as u128 |
108 | 1.50k | } <u64 as lexical_util::num::AsPrimitive>::as_u128 Line | Count | Source | 106 | 1.34k | fn as_u128(self) -> u128 { | 107 | 1.34k | self as u128 | 108 | 1.34k | } |
<i128 as lexical_util::num::AsPrimitive>::as_u128 Line | Count | Source | 106 | 154 | fn as_u128(self) -> u128 { | 107 | 154 | self as u128 | 108 | 154 | } |
Unexecuted instantiation: <u32 as lexical_util::num::AsPrimitive>::as_u128 Unexecuted instantiation: <u128 as lexical_util::num::AsPrimitive>::as_u128 |
109 | | |
110 | | #[inline(always)] |
111 | 6 | fn as_usize(self) -> usize { |
112 | 2 | self as usize |
113 | 6 | } <u32 as lexical_util::num::AsPrimitive>::as_usize Line | Count | Source | 111 | 4 | fn as_usize(self) -> usize { | 112 | 4 | self as usize | 113 | 4 | } |
Unexecuted instantiation: <u64 as lexical_util::num::AsPrimitive>::as_usize <usize as lexical_util::num::AsPrimitive>::as_usize Line | Count | Source | 111 | 2 | fn as_usize(self) -> usize { | 112 | 2 | self as usize | 113 | 2 | } |
|
114 | | |
115 | | #[inline(always)] |
116 | 5 | fn as_i8(self) -> i8 { |
117 | 1 | self as i8 |
118 | 5 | } <u32 as lexical_util::num::AsPrimitive>::as_i8 Line | Count | Source | 116 | 4 | fn as_i8(self) -> i8 { | 117 | 4 | self as i8 | 118 | 4 | } |
Unexecuted instantiation: <u64 as lexical_util::num::AsPrimitive>::as_i8 <i8 as lexical_util::num::AsPrimitive>::as_i8 Line | Count | Source | 116 | 1 | fn as_i8(self) -> i8 { | 117 | 1 | self as i8 | 118 | 1 | } |
|
119 | | |
120 | | #[inline(always)] |
121 | 3 | fn as_i16(self) -> i16 { |
122 | 1 | self as i16 |
123 | 3 | } <u32 as lexical_util::num::AsPrimitive>::as_i16 Line | Count | Source | 121 | 2 | fn as_i16(self) -> i16 { | 122 | 2 | self as i16 | 123 | 2 | } |
Unexecuted instantiation: <u64 as lexical_util::num::AsPrimitive>::as_i16 <i16 as lexical_util::num::AsPrimitive>::as_i16 Line | Count | Source | 121 | 1 | fn as_i16(self) -> i16 { | 122 | 1 | self as i16 | 123 | 1 | } |
|
124 | | |
125 | | #[inline(always)] |
126 | 8.43k | fn as_i32(self) -> i32 { |
127 | 4.21k | self as i32 |
128 | 8.43k | } <u32 as lexical_util::num::AsPrimitive>::as_i32 Line | Count | Source | 126 | 1.56k | fn as_i32(self) -> i32 { | 127 | 1.56k | self as i32 | 128 | 1.56k | } |
<i32 as lexical_util::num::AsPrimitive>::as_i32 Line | Count | Source | 126 | 4.21k | fn as_i32(self) -> i32 { | 127 | 4.21k | self as i32 | 128 | 4.21k | } |
<u64 as lexical_util::num::AsPrimitive>::as_i32 Line | Count | Source | 126 | 2.65k | fn as_i32(self) -> i32 { | 127 | 2.65k | self as i32 | 128 | 2.65k | } |
|
129 | | |
130 | | #[inline(always)] |
131 | 0 | fn as_i64(self) -> i64 { |
132 | 0 | self as i64 |
133 | 0 | } Unexecuted instantiation: <u32 as lexical_util::num::AsPrimitive>::as_i64 Unexecuted instantiation: <u64 as lexical_util::num::AsPrimitive>::as_i64 Unexecuted instantiation: <i64 as lexical_util::num::AsPrimitive>::as_i64 |
134 | | |
135 | | #[inline(always)] |
136 | 0 | fn as_i128(self) -> i128 { |
137 | 0 | self as i128 |
138 | 0 | } Unexecuted instantiation: <u32 as lexical_util::num::AsPrimitive>::as_i128 Unexecuted instantiation: <u64 as lexical_util::num::AsPrimitive>::as_i128 Unexecuted instantiation: <i128 as lexical_util::num::AsPrimitive>::as_i128 |
139 | | |
140 | | #[inline(always)] |
141 | 0 | fn as_isize(self) -> isize { |
142 | 0 | self as isize |
143 | 0 | } Unexecuted instantiation: <u32 as lexical_util::num::AsPrimitive>::as_isize Unexecuted instantiation: <u64 as lexical_util::num::AsPrimitive>::as_isize Unexecuted instantiation: <isize as lexical_util::num::AsPrimitive>::as_isize |
144 | | |
145 | | #[inline(always)] |
146 | 122 | fn as_f32(self) -> f32 { |
147 | 122 | self as f32 |
148 | 122 | } |
149 | | |
150 | | #[inline(always)] |
151 | 229 | fn as_f64(self) -> f64 { |
152 | 229 | self as f64 |
153 | 229 | } |
154 | | |
155 | | #[inline(always)] |
156 | 0 | fn from_u32(value: u32) -> Self { |
157 | 0 | value as Self |
158 | 0 | } Unexecuted instantiation: <u64 as lexical_util::num::AsPrimitive>::from_u32 Unexecuted instantiation: <usize as lexical_util::num::AsPrimitive>::from_u32 Unexecuted instantiation: <i8 as lexical_util::num::AsPrimitive>::from_u32 Unexecuted instantiation: <u32 as lexical_util::num::AsPrimitive>::from_u32 Unexecuted instantiation: <i128 as lexical_util::num::AsPrimitive>::from_u32 Unexecuted instantiation: <u8 as lexical_util::num::AsPrimitive>::from_u32 Unexecuted instantiation: <i32 as lexical_util::num::AsPrimitive>::from_u32 Unexecuted instantiation: <i16 as lexical_util::num::AsPrimitive>::from_u32 Unexecuted instantiation: <u16 as lexical_util::num::AsPrimitive>::from_u32 Unexecuted instantiation: <isize as lexical_util::num::AsPrimitive>::from_u32 Unexecuted instantiation: <i64 as lexical_util::num::AsPrimitive>::from_u32 Unexecuted instantiation: <u128 as lexical_util::num::AsPrimitive>::from_u32 |
159 | | |
160 | | #[inline(always)] |
161 | | fn from_u64(value: u64) -> Self { |
162 | | value as Self |
163 | | } |
164 | | |
165 | | #[cfg(feature = "f16")] |
166 | | #[inline(always)] |
167 | | fn as_f16(self) -> f16 { |
168 | | f16::from_f32(self as f32) |
169 | | } |
170 | | |
171 | | #[cfg(feature = "f16")] |
172 | | #[inline(always)] |
173 | | fn as_bf16(self) -> bf16 { |
174 | | bf16::from_f32(self as f32) |
175 | | } |
176 | | } |
177 | | )*) |
178 | | } |
179 | | |
180 | | as_primitive! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize f32 f64 } |
181 | | |
182 | | #[cfg(feature = "f16")] |
183 | | macro_rules! half_as_primitive { |
184 | | ($($t:ty)*) => ($( |
185 | | impl AsPrimitive for $t { |
186 | | #[inline(always)] |
187 | | fn as_u8(self) -> u8 { |
188 | | self.as_f32() as u8 |
189 | | } |
190 | | |
191 | | #[inline(always)] |
192 | | fn as_u16(self) -> u16 { |
193 | | self.as_f32() as u16 |
194 | | } |
195 | | |
196 | | #[inline(always)] |
197 | | fn as_u32(self) -> u32 { |
198 | | self.as_f32() as u32 |
199 | | } |
200 | | |
201 | | #[inline(always)] |
202 | | fn as_u64(self) -> u64 { |
203 | | self.as_f32() as u64 |
204 | | } |
205 | | |
206 | | #[inline(always)] |
207 | | fn as_u128(self) -> u128 { |
208 | | self.as_f32() as u128 |
209 | | } |
210 | | |
211 | | #[inline(always)] |
212 | | fn as_usize(self) -> usize { |
213 | | self.as_f32() as usize |
214 | | } |
215 | | |
216 | | #[inline(always)] |
217 | | fn as_i8(self) -> i8 { |
218 | | self.as_f32() as i8 |
219 | | } |
220 | | |
221 | | #[inline(always)] |
222 | | fn as_i16(self) -> i16 { |
223 | | self.as_f32() as i16 |
224 | | } |
225 | | |
226 | | #[inline(always)] |
227 | | fn as_i32(self) -> i32 { |
228 | | self.as_f32() as i32 |
229 | | } |
230 | | |
231 | | #[inline(always)] |
232 | | fn as_i64(self) -> i64 { |
233 | | self.as_f32() as i64 |
234 | | } |
235 | | |
236 | | #[inline(always)] |
237 | | fn as_i128(self) -> i128 { |
238 | | self.as_f32() as i128 |
239 | | } |
240 | | |
241 | | #[inline(always)] |
242 | | fn as_isize(self) -> isize { |
243 | | self.as_f32() as isize |
244 | | } |
245 | | |
246 | | #[inline(always)] |
247 | | fn as_f32(self) -> f32 { |
248 | | self.as_f32() as f32 |
249 | | } |
250 | | |
251 | | #[inline(always)] |
252 | | fn as_f64(self) -> f64 { |
253 | | self.as_f32() as f64 |
254 | | } |
255 | | |
256 | | #[inline(always)] |
257 | | #[allow(clippy::as_underscore)] // reason="intentionally used in a generic sense" |
258 | | fn from_u32(value: u32) -> Self { |
259 | | Self::from_f32(value as _) |
260 | | } |
261 | | |
262 | | #[inline(always)] |
263 | | fn from_u64(value: u64) -> Self { |
264 | | _ = value; |
265 | | unimplemented!() |
266 | | } |
267 | | |
268 | | #[inline(always)] |
269 | | fn as_f16(self) -> f16 { |
270 | | f16::from_f32(self.as_f32()) |
271 | | } |
272 | | |
273 | | #[inline(always)] |
274 | | fn as_bf16(self) -> bf16 { |
275 | | bf16::from_f32(self.as_f32()) |
276 | | } |
277 | | } |
278 | | )*) |
279 | | } |
280 | | |
281 | | #[cfg(feature = "f16")] |
282 | | half_as_primitive! { f16 bf16 } |
283 | | |
284 | | // AS CAST |
285 | | // ------- |
286 | | |
287 | | /// An interface for casting between machine scalars, as if `as` was used. |
288 | | /// |
289 | | /// All values that the type can be cast to must be [`primitive`] values. |
290 | | /// |
291 | | /// [`primitive`]: https://doc.rust-lang.org/rust-by-example/primitives.html |
292 | | pub trait AsCast: AsPrimitive { |
293 | | /// Creates a number from another value that can be converted into |
294 | | /// a primitive via the [`AsPrimitive`] trait. |
295 | | /// |
296 | | /// # Examples |
297 | | /// |
298 | | /// ```rust |
299 | | /// use lexical_util::num::AsCast; |
300 | | /// |
301 | | /// assert_eq!(u8::as_cast(256u16), 256u16 as u8); // 0 |
302 | | /// ``` |
303 | | fn as_cast<N: AsPrimitive>(n: N) -> Self; |
304 | | } |
305 | | |
306 | | /// Allows the high-level conversion of generic types as if `as` was used. |
307 | | /// |
308 | | /// # Examples |
309 | | /// |
310 | | /// ```rust |
311 | | /// use lexical_util::num::as_cast; |
312 | | /// |
313 | | /// assert_eq!(as_cast::<u8, u16>(256u16), 256u16 as u8); // 0 |
314 | | /// ``` |
315 | | #[inline(always)] |
316 | 1.39k | pub fn as_cast<U: AsCast, T: AsCast>(t: T) -> U { |
317 | 1.39k | U::as_cast(t) |
318 | 1.39k | } Unexecuted instantiation: lexical_util::num::as_cast::<u64, u32> Unexecuted instantiation: lexical_util::num::as_cast::<u64, u64> lexical_util::num::as_cast::<usize, usize> Line | Count | Source | 316 | 2 | pub fn as_cast<U: AsCast, T: AsCast>(t: T) -> U { | 317 | 2 | U::as_cast(t) | 318 | 2 | } |
lexical_util::num::as_cast::<usize, u32> Line | Count | Source | 316 | 4 | pub fn as_cast<U: AsCast, T: AsCast>(t: T) -> U { | 317 | 4 | U::as_cast(t) | 318 | 4 | } |
lexical_util::num::as_cast::<i8, i8> Line | Count | Source | 316 | 1 | pub fn as_cast<U: AsCast, T: AsCast>(t: T) -> U { | 317 | 1 | U::as_cast(t) | 318 | 1 | } |
lexical_util::num::as_cast::<i8, u32> Line | Count | Source | 316 | 4 | pub fn as_cast<U: AsCast, T: AsCast>(t: T) -> U { | 317 | 4 | U::as_cast(t) | 318 | 4 | } |
lexical_util::num::as_cast::<u128, u64> Line | Count | Source | 316 | 654 | pub fn as_cast<U: AsCast, T: AsCast>(t: T) -> U { | 317 | 654 | U::as_cast(t) | 318 | 654 | } |
lexical_util::num::as_cast::<u32, u32> Line | Count | Source | 316 | 23 | pub fn as_cast<U: AsCast, T: AsCast>(t: T) -> U { | 317 | 23 | U::as_cast(t) | 318 | 23 | } |
lexical_util::num::as_cast::<u128, u64> Line | Count | Source | 316 | 693 | pub fn as_cast<U: AsCast, T: AsCast>(t: T) -> U { | 317 | 693 | U::as_cast(t) | 318 | 693 | } |
Unexecuted instantiation: lexical_util::num::as_cast::<i128, u32> Unexecuted instantiation: lexical_util::num::as_cast::<i128, i128> Unexecuted instantiation: lexical_util::num::as_cast::<u8, u32> Unexecuted instantiation: lexical_util::num::as_cast::<u8, u8> lexical_util::num::as_cast::<i32, u32> Line | Count | Source | 316 | 6 | pub fn as_cast<U: AsCast, T: AsCast>(t: T) -> U { | 317 | 6 | U::as_cast(t) | 318 | 6 | } |
Unexecuted instantiation: lexical_util::num::as_cast::<i32, i32> lexical_util::num::as_cast::<i16, u32> Line | Count | Source | 316 | 2 | pub fn as_cast<U: AsCast, T: AsCast>(t: T) -> U { | 317 | 2 | U::as_cast(t) | 318 | 2 | } |
lexical_util::num::as_cast::<i16, i16> Line | Count | Source | 316 | 1 | pub fn as_cast<U: AsCast, T: AsCast>(t: T) -> U { | 317 | 1 | U::as_cast(t) | 318 | 1 | } |
lexical_util::num::as_cast::<u16, u32> Line | Count | Source | 316 | 2 | pub fn as_cast<U: AsCast, T: AsCast>(t: T) -> U { | 317 | 2 | U::as_cast(t) | 318 | 2 | } |
lexical_util::num::as_cast::<u16, u16> Line | Count | Source | 316 | 1 | pub fn as_cast<U: AsCast, T: AsCast>(t: T) -> U { | 317 | 1 | U::as_cast(t) | 318 | 1 | } |
Unexecuted instantiation: lexical_util::num::as_cast::<isize, u32> Unexecuted instantiation: lexical_util::num::as_cast::<isize, isize> Unexecuted instantiation: lexical_util::num::as_cast::<i64, u32> Unexecuted instantiation: lexical_util::num::as_cast::<i64, i64> Unexecuted instantiation: lexical_util::num::as_cast::<u128, u32> Unexecuted instantiation: lexical_util::num::as_cast::<u128, u128> |
319 | | |
320 | | macro_rules! as_cast { |
321 | | ($($t:ty, $meth:ident ; )*) => ($( |
322 | | impl AsCast for $t { |
323 | | #[inline(always)] |
324 | | #[allow(clippy::as_underscore)] // reason="intentional due to generic API" |
325 | 9.07M | fn as_cast<N: AsPrimitive>(n: N) -> $t { |
326 | 9.07M | n.$meth() as _ |
327 | 9.07M | } <i32 as lexical_util::num::AsCast>::as_cast::<u32> Line | Count | Source | 325 | 569 | fn as_cast<N: AsPrimitive>(n: N) -> $t { | 326 | 569 | n.$meth() as _ | 327 | 569 | } |
Unexecuted instantiation: <u64 as lexical_util::num::AsCast>::as_cast::<u32> Unexecuted instantiation: <u64 as lexical_util::num::AsCast>::as_cast::<u64> <usize as lexical_util::num::AsCast>::as_cast::<usize> Line | Count | Source | 325 | 2 | fn as_cast<N: AsPrimitive>(n: N) -> $t { | 326 | 2 | n.$meth() as _ | 327 | 2 | } |
<usize as lexical_util::num::AsCast>::as_cast::<u32> Line | Count | Source | 325 | 4 | fn as_cast<N: AsPrimitive>(n: N) -> $t { | 326 | 4 | n.$meth() as _ | 327 | 4 | } |
Unexecuted instantiation: <usize as lexical_util::num::AsCast>::as_cast::<u64> <i8 as lexical_util::num::AsCast>::as_cast::<i8> Line | Count | Source | 325 | 1 | fn as_cast<N: AsPrimitive>(n: N) -> $t { | 326 | 1 | n.$meth() as _ | 327 | 1 | } |
<i8 as lexical_util::num::AsCast>::as_cast::<u32> Line | Count | Source | 325 | 4 | fn as_cast<N: AsPrimitive>(n: N) -> $t { | 326 | 4 | n.$meth() as _ | 327 | 4 | } |
Unexecuted instantiation: <i8 as lexical_util::num::AsCast>::as_cast::<u64> <u16 as lexical_util::num::AsCast>::as_cast::<i16> Line | Count | Source | 325 | 38 | fn as_cast<N: AsPrimitive>(n: N) -> $t { | 326 | 38 | n.$meth() as _ | 327 | 38 | } |
<u128 as lexical_util::num::AsCast>::as_cast::<i128> Line | Count | Source | 325 | 154 | fn as_cast<N: AsPrimitive>(n: N) -> $t { | 326 | 154 | n.$meth() as _ | 327 | 154 | } |
<u128 as lexical_util::num::AsCast>::as_cast::<u64> Line | Count | Source | 325 | 654 | fn as_cast<N: AsPrimitive>(n: N) -> $t { | 326 | 654 | n.$meth() as _ | 327 | 654 | } |
<u32 as lexical_util::num::AsCast>::as_cast::<u32> Line | Count | Source | 325 | 23 | fn as_cast<N: AsPrimitive>(n: N) -> $t { | 326 | 23 | n.$meth() as _ | 327 | 23 | } |
Unexecuted instantiation: <u32 as lexical_util::num::AsCast>::as_cast::<u64> <u128 as lexical_util::num::AsCast>::as_cast::<u64> Line | Count | Source | 325 | 693 | fn as_cast<N: AsPrimitive>(n: N) -> $t { | 326 | 693 | n.$meth() as _ | 327 | 693 | } |
<i32 as lexical_util::num::AsCast>::as_cast::<u64> Line | Count | Source | 325 | 1.78k | fn as_cast<N: AsPrimitive>(n: N) -> $t { | 326 | 1.78k | n.$meth() as _ | 327 | 1.78k | } |
<u8 as lexical_util::num::AsCast>::as_cast::<i8> Line | Count | Source | 325 | 39 | fn as_cast<N: AsPrimitive>(n: N) -> $t { | 326 | 39 | n.$meth() as _ | 327 | 39 | } |
<f32 as lexical_util::num::AsCast>::as_cast::<u64> Line | Count | Source | 325 | 122 | fn as_cast<N: AsPrimitive>(n: N) -> $t { | 326 | 122 | n.$meth() as _ | 327 | 122 | } |
<u32 as lexical_util::num::AsCast>::as_cast::<u64> Line | Count | Source | 325 | 2.89k | fn as_cast<N: AsPrimitive>(n: N) -> $t { | 326 | 2.89k | n.$meth() as _ | 327 | 2.89k | } |
<u64 as lexical_util::num::AsCast>::as_cast::<u64> Line | Count | Source | 325 | 4.26M | fn as_cast<N: AsPrimitive>(n: N) -> $t { | 326 | 4.26M | n.$meth() as _ | 327 | 4.26M | } |
<i32 as lexical_util::num::AsCast>::as_cast::<u32> Line | Count | Source | 325 | 992 | fn as_cast<N: AsPrimitive>(n: N) -> $t { | 326 | 992 | n.$meth() as _ | 327 | 992 | } |
Unexecuted instantiation: <i128 as lexical_util::num::AsCast>::as_cast::<u32> Unexecuted instantiation: <i128 as lexical_util::num::AsCast>::as_cast::<i128> Unexecuted instantiation: <i128 as lexical_util::num::AsCast>::as_cast::<u64> Unexecuted instantiation: <u8 as lexical_util::num::AsCast>::as_cast::<u32> Unexecuted instantiation: <u8 as lexical_util::num::AsCast>::as_cast::<u8> Unexecuted instantiation: <u8 as lexical_util::num::AsCast>::as_cast::<u64> <i32 as lexical_util::num::AsCast>::as_cast::<u32> Line | Count | Source | 325 | 6 | fn as_cast<N: AsPrimitive>(n: N) -> $t { | 326 | 6 | n.$meth() as _ | 327 | 6 | } |
Unexecuted instantiation: <i32 as lexical_util::num::AsCast>::as_cast::<i32> Unexecuted instantiation: <i32 as lexical_util::num::AsCast>::as_cast::<u64> <u64 as lexical_util::num::AsCast>::as_cast::<isize> Line | Count | Source | 325 | 40 | fn as_cast<N: AsPrimitive>(n: N) -> $t { | 326 | 40 | n.$meth() as _ | 327 | 40 | } |
<i16 as lexical_util::num::AsCast>::as_cast::<u32> Line | Count | Source | 325 | 2 | fn as_cast<N: AsPrimitive>(n: N) -> $t { | 326 | 2 | n.$meth() as _ | 327 | 2 | } |
<i16 as lexical_util::num::AsCast>::as_cast::<i16> Line | Count | Source | 325 | 1 | fn as_cast<N: AsPrimitive>(n: N) -> $t { | 326 | 1 | n.$meth() as _ | 327 | 1 | } |
Unexecuted instantiation: <i16 as lexical_util::num::AsCast>::as_cast::<u64> <u64 as lexical_util::num::AsCast>::as_cast::<u64> Line | Count | Source | 325 | 4.79M | fn as_cast<N: AsPrimitive>(n: N) -> $t { | 326 | 4.79M | n.$meth() as _ | 327 | 4.79M | } |
<i32 as lexical_util::num::AsCast>::as_cast::<u64> Line | Count | Source | 325 | 870 | fn as_cast<N: AsPrimitive>(n: N) -> $t { | 326 | 870 | n.$meth() as _ | 327 | 870 | } |
<f64 as lexical_util::num::AsCast>::as_cast::<u64> Line | Count | Source | 325 | 229 | fn as_cast<N: AsPrimitive>(n: N) -> $t { | 326 | 229 | n.$meth() as _ | 327 | 229 | } |
<u64 as lexical_util::num::AsCast>::as_cast::<i64> Line | Count | Source | 325 | 31 | fn as_cast<N: AsPrimitive>(n: N) -> $t { | 326 | 31 | n.$meth() as _ | 327 | 31 | } |
<u16 as lexical_util::num::AsCast>::as_cast::<u32> Line | Count | Source | 325 | 2 | fn as_cast<N: AsPrimitive>(n: N) -> $t { | 326 | 2 | n.$meth() as _ | 327 | 2 | } |
<u16 as lexical_util::num::AsCast>::as_cast::<u16> Line | Count | Source | 325 | 1 | fn as_cast<N: AsPrimitive>(n: N) -> $t { | 326 | 1 | n.$meth() as _ | 327 | 1 | } |
Unexecuted instantiation: <u16 as lexical_util::num::AsCast>::as_cast::<u64> Unexecuted instantiation: <isize as lexical_util::num::AsCast>::as_cast::<u32> Unexecuted instantiation: <isize as lexical_util::num::AsCast>::as_cast::<isize> Unexecuted instantiation: <isize as lexical_util::num::AsCast>::as_cast::<u64> Unexecuted instantiation: <i64 as lexical_util::num::AsCast>::as_cast::<u32> Unexecuted instantiation: <i64 as lexical_util::num::AsCast>::as_cast::<i64> Unexecuted instantiation: <i64 as lexical_util::num::AsCast>::as_cast::<u64> Unexecuted instantiation: <u128 as lexical_util::num::AsCast>::as_cast::<u32> Unexecuted instantiation: <u128 as lexical_util::num::AsCast>::as_cast::<u128> Unexecuted instantiation: <u128 as lexical_util::num::AsCast>::as_cast::<u64> <u32 as lexical_util::num::AsCast>::as_cast::<i32> Line | Count | Source | 325 | 37 | fn as_cast<N: AsPrimitive>(n: N) -> $t { | 326 | 37 | n.$meth() as _ | 327 | 37 | } |
|
328 | | } |
329 | | )*); |
330 | | } |
331 | | |
332 | | as_cast!( |
333 | | u8, as_u8 ; |
334 | | u16, as_u16 ; |
335 | | u32, as_u32 ; |
336 | | u64, as_u64 ; |
337 | | u128, as_u128 ; |
338 | | usize, as_usize ; |
339 | | i8, as_i8 ; |
340 | | i16, as_i16 ; |
341 | | i32, as_i32 ; |
342 | | i64, as_i64 ; |
343 | | i128, as_i128 ; |
344 | | isize, as_isize ; |
345 | | f32, as_f32 ; |
346 | | f64, as_f64 ; |
347 | | ); |
348 | | |
349 | | #[cfg(feature = "f16")] |
350 | | as_cast!( |
351 | | f16, as_f16 ; |
352 | | bf16, as_bf16 ; |
353 | | ); |
354 | | |
355 | | // PRIMITIVE |
356 | | // --------- |
357 | | |
358 | | /// The base trait for all [`primitive`] types. |
359 | | /// |
360 | | /// [`primitive`]: https://doc.rust-lang.org/rust-by-example/primitives.html |
361 | | pub trait Primitive: 'static + fmt::Debug + fmt::Display + AsCast {} |
362 | | |
363 | | macro_rules! primitive { |
364 | | ($($t:ty)*) => ($( |
365 | | impl Primitive for $t {} |
366 | | )*) |
367 | | } |
368 | | |
369 | | primitive! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize f32 f64 } |
370 | | |
371 | | #[cfg(feature = "f16")] |
372 | | primitive! { f16 bf16 } |
373 | | |
374 | | // NUMBER |
375 | | // ------ |
376 | | |
377 | | /// The base trait for all numbers (integers and floating-point numbers). |
378 | | pub trait Number: |
379 | | Default + |
380 | | Primitive + |
381 | | // Operations |
382 | | ops::Add<Output=Self> + |
383 | | ops::AddAssign + |
384 | | ops::Div<Output=Self> + |
385 | | ops::DivAssign + |
386 | | ops::Mul<Output=Self> + |
387 | | ops::MulAssign + |
388 | | ops::Rem<Output=Self> + |
389 | | ops::RemAssign + |
390 | | ops::Sub<Output=Self> + |
391 | | ops::SubAssign |
392 | | { |
393 | | /// If the number can hold negative values. |
394 | | const IS_SIGNED: bool; |
395 | | } |
396 | | |
397 | | macro_rules! number_impl { |
398 | | ($($t:tt $is_signed:literal ; )*) => ($( |
399 | | impl Number for $t { |
400 | | const IS_SIGNED: bool = $is_signed; |
401 | | } |
402 | | )*) |
403 | | } |
404 | | |
405 | | number_impl! { |
406 | | u8 false ; |
407 | | u16 false ; |
408 | | u32 false ; |
409 | | u64 false ; |
410 | | u128 false ; |
411 | | usize false ; |
412 | | i8 true ; |
413 | | i16 true ; |
414 | | i32 true ; |
415 | | i64 true ; |
416 | | i128 true ; |
417 | | isize true ; |
418 | | f32 true ; |
419 | | f64 true ; |
420 | | // f128 true |
421 | | } |
422 | | |
423 | | #[cfg(feature = "f16")] |
424 | | number_impl! { |
425 | | f16 true ; |
426 | | bf16 true ; |
427 | | } |
428 | | |
429 | | // INTEGER |
430 | | // ------- |
431 | | |
432 | | /// The base trait for all signed and unsigned [`integers`]. |
433 | | /// |
434 | | /// [`integers`]: https://en.wikipedia.org/wiki/Integer_(computer_science) |
435 | | pub trait Integer: |
436 | | // Basic |
437 | | Number + Eq + Ord + |
438 | | // Operations |
439 | | ops::BitAnd<Output=Self> + |
440 | | ops::BitAndAssign + |
441 | | ops::BitOr<Output=Self> + |
442 | | ops::BitOrAssign + |
443 | | ops::BitXor<Output=Self> + |
444 | | ops::BitXorAssign + |
445 | | ops::Not<Output=Self> + |
446 | | ops::Shl<Self, Output=Self> + |
447 | | ops::Shl<i32, Output=Self> + |
448 | | ops::ShlAssign<i32> + |
449 | | ops::Shr<i32, Output=Self> + |
450 | | ops::ShrAssign<i32> + |
451 | | { |
452 | | // CONSTANTS |
453 | | /// A value equal to `0`. |
454 | | const ZERO: Self; |
455 | | |
456 | | /// A value equal to `1`. |
457 | | const ONE: Self; |
458 | | |
459 | | /// A value equal to `2`. |
460 | | const TWO: Self; |
461 | | |
462 | | /// The largest value that can be represented by this integer type. |
463 | | /// |
464 | | /// See [`u32::MAX`]. |
465 | | const MAX: Self; |
466 | | |
467 | | /// The smallest value that can be represented by this integer type. |
468 | | /// |
469 | | /// See [`u32::MIN`]. |
470 | | const MIN: Self; |
471 | | |
472 | | /// The size of this integer type in bits. |
473 | | /// |
474 | | /// See [`u32::BITS`]. |
475 | | const BITS: usize; |
476 | | |
477 | | // FUNCTIONS (INHERITED) |
478 | | /// Returns the number of leading zeros in the binary representation |
479 | | /// of `self`. |
480 | | /// |
481 | | /// See [`u32::leading_zeros`]. |
482 | | fn leading_zeros(self) -> u32; |
483 | | |
484 | | /// Returns the number of trailing zeros in the binary representation |
485 | | /// of `self`. |
486 | | /// |
487 | | /// See [`u32::trailing_zeros`]. |
488 | | fn trailing_zeros(self) -> u32; |
489 | | |
490 | | /// Raises self to the power of `exp`, using exponentiation by squaring. |
491 | | /// |
492 | | /// See [`u32::pow`]. |
493 | | fn pow(self, exp: u32) -> Self; |
494 | | |
495 | | /// Checked exponentiation. Computes `self.pow(exp)`, returning |
496 | | /// `None` if overflow occurred. |
497 | | /// |
498 | | /// See [`u32::checked_pow`]. |
499 | | fn checked_pow(self, exp: u32) -> Option<Self>; |
500 | | |
501 | | /// Raises self to the power of `exp`, using exponentiation by squaring. |
502 | | /// |
503 | | /// Returns a tuple of the exponentiation along with a bool indicating |
504 | | /// whether an overflow happened. |
505 | | /// |
506 | | /// See [`u32::overflowing_pow`]. |
507 | | fn overflowing_pow(self, exp: u32) -> (Self, bool); |
508 | | |
509 | | /// Checked integer addition. Computes `self + i`, returning `None` if |
510 | | /// overflow occurred. |
511 | | /// |
512 | | /// See [`u32::checked_add`]. |
513 | | fn checked_add(self, i: Self) -> Option<Self>; |
514 | | |
515 | | /// Checked integer subtraction. Computes `self - i`, returning `None` |
516 | | /// if overflow occurred. |
517 | | /// |
518 | | /// See [`u32::checked_sub`]. |
519 | | fn checked_sub(self, i: Self) -> Option<Self>; |
520 | | |
521 | | /// Checked integer multiplication. Computes `self * rhs`, returning `None` |
522 | | /// if overflow occurred. |
523 | | /// |
524 | | /// See [`u32::checked_mul`]. |
525 | | fn checked_mul(self, i: Self) -> Option<Self>; |
526 | | |
527 | | /// Calculates `self + i`. |
528 | | /// |
529 | | /// Returns a tuple of the addition along with a boolean indicating whether |
530 | | /// an arithmetic overflow would occur. If an overflow would have occurred |
531 | | /// then the wrapped value is returned. See [`u32::overflowing_add`]. |
532 | | fn overflowing_add(self, i: Self) -> (Self, bool); |
533 | | |
534 | | /// Calculates `self - i`. |
535 | | /// |
536 | | /// Returns a tuple of the addition along with a boolean indicating whether |
537 | | /// an arithmetic overflow would occur. If an overflow would have occurred |
538 | | /// then the wrapped value is returned. See [`u32::overflowing_sub`]. |
539 | | fn overflowing_sub(self, i: Self) -> (Self, bool); |
540 | | |
541 | | /// Calculates `self * i`. |
542 | | /// |
543 | | /// Returns a tuple of the addition along with a boolean indicating whether |
544 | | /// an arithmetic overflow would occur. If an overflow would have occurred |
545 | | /// then the wrapped value is returned. See [`u32::overflowing_mul`]. |
546 | | fn overflowing_mul(self, i: Self) -> (Self, bool); |
547 | | |
548 | | /// Wrapping (modular) addition. Computes `self + i`, wrapping around at |
549 | | /// the boundary of the type. |
550 | | /// |
551 | | /// See [`u32::wrapping_add`]. |
552 | | fn wrapping_add(self, i: Self) -> Self; |
553 | | |
554 | | /// Wrapping (modular) subtraction. Computes `self - i`, wrapping around at |
555 | | /// the boundary of the type. |
556 | | /// |
557 | | /// See [`u32::wrapping_sub`]. |
558 | | fn wrapping_sub(self, i: Self) -> Self; |
559 | | |
560 | | /// Wrapping (modular) multiplication. Computes `self * i`, wrapping around at |
561 | | /// the boundary of the type. |
562 | | /// |
563 | | /// See [`u32::wrapping_mul`]. |
564 | | fn wrapping_mul(self, i: Self) -> Self; |
565 | | |
566 | | /// Wrapping (modular) negation. Computes `-self`, wrapping around at |
567 | | /// the boundary of the type. |
568 | | /// |
569 | | /// See [`u32::wrapping_neg`]. |
570 | | fn wrapping_neg(self) -> Self; |
571 | | |
572 | | /// Saturating integer addition. Computes `self + i`, saturating at the |
573 | | /// numeric bounds instead of overflowing. |
574 | | /// |
575 | | /// See [`u32::saturating_add`]. |
576 | | fn saturating_add(self, i: Self) -> Self; |
577 | | |
578 | | /// Saturating integer subtraction. Computes `self - i`, saturating at the |
579 | | /// numeric bounds instead of overflowing. |
580 | | /// |
581 | | /// See [`u32::saturating_sub`]. |
582 | | fn saturating_sub(self, i: Self) -> Self; |
583 | | |
584 | | /// Saturating integer multiplication. Computes `self * i`, saturating at |
585 | | /// the numeric bounds instead of overflowing. |
586 | | /// |
587 | | /// See [`u32::saturating_mul`]. |
588 | | fn saturating_mul(self, i: Self) -> Self; |
589 | | |
590 | | /// Get the fast ceiling of the quotient from integer division. |
591 | | /// |
592 | | /// The remainder may wrap to the numerical boundaries for the type. |
593 | | /// See [`u32::div_ceil`]. |
594 | | /// |
595 | | /// # Examples |
596 | | /// |
597 | | /// ```rust |
598 | | /// use lexical_util::num::Integer; |
599 | | /// |
600 | | /// assert_eq!(250u16.ceil_divmod(10), (25, 0)); |
601 | | /// assert_eq!(256u16.ceil_divmod(10), (26, -4)); |
602 | | /// assert_eq!(i32::MAX.ceil_divmod(-2), (-0x3FFFFFFE, 3)); |
603 | | /// |
604 | | /// // notice how `-1` wraps since `i32` cannot hold `i128::MAX`. |
605 | | /// assert_eq!((i128::MAX - 1).ceil_divmod(i128::MAX), (1, -1)); |
606 | | /// ``` |
607 | | #[inline(always)] |
608 | | fn ceil_divmod(self, y: Self) -> (Self, i32) { |
609 | | let q = self / y; |
610 | | let r = self % y; |
611 | | match r == Self::ZERO { |
612 | | true => (q, i32::as_cast(r)), |
613 | | false => (q + Self::ONE, i32::as_cast(r) - i32::as_cast(y)) |
614 | | } |
615 | | } |
616 | | |
617 | | /// Get the fast ceiling of the quotient from integer division. |
618 | | /// |
619 | | /// This is identical to [`u32::div_ceil`]. |
620 | | /// |
621 | | /// # Examples |
622 | | /// |
623 | | /// ```rust |
624 | | /// use lexical_util::num::Integer; |
625 | | /// |
626 | | /// assert_eq!(250u16.ceil_div(10), 25); |
627 | | /// assert_eq!(256u16.ceil_div(10), 26); |
628 | | /// assert_eq!(i32::MAX.ceil_div(-2), -0x3FFFFFFE); |
629 | | /// assert_eq!((i128::MAX - 1).ceil_div(i128::MAX), 1); |
630 | | /// ``` |
631 | | #[inline(always)] |
632 | | fn ceil_div(self, y: Self) -> Self { |
633 | | self.ceil_divmod(y).0 |
634 | | } |
635 | | |
636 | | /// Get the fast ceiling modulus from integer division. |
637 | | /// |
638 | | /// The remainder is not guaranteed to be valid since it can |
639 | | /// overflow if the remainder is not 0. See [`Self::ceil_divmod`]. |
640 | | /// |
641 | | /// # Examples |
642 | | /// |
643 | | /// ```rust |
644 | | /// use lexical_util::num::Integer; |
645 | | /// |
646 | | /// assert_eq!(250u16.ceil_mod(10), 0); |
647 | | /// assert_eq!(256u16.ceil_mod(10), -4); |
648 | | /// assert_eq!(i32::MAX.ceil_mod(-2), 3); |
649 | | /// |
650 | | /// // notice how `-1` wraps since `i32` cannot hold `i128::MAX`. |
651 | | /// assert_eq!((i128::MAX - 1).ceil_mod(i128::MAX), -1); |
652 | | /// ``` |
653 | | #[inline(always)] |
654 | | fn ceil_mod(self, y: Self) -> i32 { |
655 | | self.ceil_divmod(y).1 |
656 | | } |
657 | | |
658 | | // PROPERTIES |
659 | | |
660 | | /// Get the number of bits in a value. |
661 | | /// |
662 | | /// # Examples |
663 | | /// |
664 | | /// ```rust |
665 | | /// use lexical_util::num::Integer; |
666 | | /// |
667 | | /// assert_eq!(1u64.bit_length(), 1); |
668 | | /// assert_eq!(2u64.bit_length(), 2); |
669 | | /// assert_eq!(3u64.bit_length(), 2); |
670 | | /// assert_eq!(16u64.bit_length(), 5); |
671 | | /// ``` |
672 | | #[inline(always)] |
673 | | fn bit_length(self) -> u32 { |
674 | | Self::BITS as u32 - self.leading_zeros() |
675 | | } |
676 | | |
677 | | /// Returns true if the least-significant bit is odd. |
678 | | #[inline(always)] |
679 | 1.96k | fn is_odd(self) -> bool { |
680 | 1.96k | self & Self::ONE == Self::ONE |
681 | 1.96k | } <u32 as lexical_util::num::Integer>::is_odd Line | Count | Source | 679 | 992 | fn is_odd(self) -> bool { | 680 | 992 | self & Self::ONE == Self::ONE | 681 | 992 | } |
<u32 as lexical_util::num::Integer>::is_odd Line | Count | Source | 679 | 973 | fn is_odd(self) -> bool { | 680 | 973 | self & Self::ONE == Self::ONE | 681 | 973 | } |
|
682 | | |
683 | | /// Returns true if the least-significant bit is even. |
684 | | #[inline(always)] |
685 | 1.96k | fn is_even(self) -> bool { |
686 | 1.96k | !self.is_odd() |
687 | 1.96k | } <u32 as lexical_util::num::Integer>::is_even Line | Count | Source | 685 | 992 | fn is_even(self) -> bool { | 686 | 992 | !self.is_odd() | 687 | 992 | } |
<u32 as lexical_util::num::Integer>::is_even Line | Count | Source | 685 | 973 | fn is_even(self) -> bool { | 686 | 973 | !self.is_odd() | 687 | 973 | } |
|
688 | | |
689 | | /// Get the maximum number of digits before the slice will overflow. |
690 | | /// |
691 | | /// This is effectively the `floor(log(2^BITS-1, radix))`, but we can |
692 | | /// try to go a bit lower without worrying too much. |
693 | | #[inline(always)] |
694 | 263 | fn overflow_digits(radix: u32) -> usize { |
695 | | // this is heavily optimized for base10 and it's a way under estimate |
696 | | // that said, it's fast and works. |
697 | 263 | if radix <= 16 { |
698 | 263 | mem::size_of::<Self>() * 2 - Self::IS_SIGNED as usize |
699 | | } else { |
700 | | // way under approximation but always works and is fast |
701 | 0 | mem::size_of::<Self>() |
702 | | } |
703 | 263 | } <u64 as lexical_util::num::Integer>::overflow_digits Line | Count | Source | 694 | 11 | fn overflow_digits(radix: u32) -> usize { | 695 | | // this is heavily optimized for base10 and it's a way under estimate | 696 | | // that said, it's fast and works. | 697 | 11 | if radix <= 16 { | 698 | 11 | mem::size_of::<Self>() * 2 - Self::IS_SIGNED as usize | 699 | | } else { | 700 | | // way under approximation but always works and is fast | 701 | 0 | mem::size_of::<Self>() | 702 | | } | 703 | 11 | } |
<usize as lexical_util::num::Integer>::overflow_digits Line | Count | Source | 694 | 12 | fn overflow_digits(radix: u32) -> usize { | 695 | | // this is heavily optimized for base10 and it's a way under estimate | 696 | | // that said, it's fast and works. | 697 | 12 | if radix <= 16 { | 698 | 12 | mem::size_of::<Self>() * 2 - Self::IS_SIGNED as usize | 699 | | } else { | 700 | | // way under approximation but always works and is fast | 701 | 0 | mem::size_of::<Self>() | 702 | | } | 703 | 12 | } |
<i8 as lexical_util::num::Integer>::overflow_digits Line | Count | Source | 694 | 31 | fn overflow_digits(radix: u32) -> usize { | 695 | | // this is heavily optimized for base10 and it's a way under estimate | 696 | | // that said, it's fast and works. | 697 | 31 | if radix <= 16 { | 698 | 31 | mem::size_of::<Self>() * 2 - Self::IS_SIGNED as usize | 699 | | } else { | 700 | | // way under approximation but always works and is fast | 701 | 0 | mem::size_of::<Self>() | 702 | | } | 703 | 31 | } |
<u32 as lexical_util::num::Integer>::overflow_digits Line | Count | Source | 694 | 15 | fn overflow_digits(radix: u32) -> usize { | 695 | | // this is heavily optimized for base10 and it's a way under estimate | 696 | | // that said, it's fast and works. | 697 | 15 | if radix <= 16 { | 698 | 15 | mem::size_of::<Self>() * 2 - Self::IS_SIGNED as usize | 699 | | } else { | 700 | | // way under approximation but always works and is fast | 701 | 0 | mem::size_of::<Self>() | 702 | | } | 703 | 15 | } |
<i128 as lexical_util::num::Integer>::overflow_digits Line | Count | Source | 694 | 30 | fn overflow_digits(radix: u32) -> usize { | 695 | | // this is heavily optimized for base10 and it's a way under estimate | 696 | | // that said, it's fast and works. | 697 | 30 | if radix <= 16 { | 698 | 30 | mem::size_of::<Self>() * 2 - Self::IS_SIGNED as usize | 699 | | } else { | 700 | | // way under approximation but always works and is fast | 701 | 0 | mem::size_of::<Self>() | 702 | | } | 703 | 30 | } |
<u8 as lexical_util::num::Integer>::overflow_digits Line | Count | Source | 694 | 11 | fn overflow_digits(radix: u32) -> usize { | 695 | | // this is heavily optimized for base10 and it's a way under estimate | 696 | | // that said, it's fast and works. | 697 | 11 | if radix <= 16 { | 698 | 11 | mem::size_of::<Self>() * 2 - Self::IS_SIGNED as usize | 699 | | } else { | 700 | | // way under approximation but always works and is fast | 701 | 0 | mem::size_of::<Self>() | 702 | | } | 703 | 11 | } |
<i32 as lexical_util::num::Integer>::overflow_digits Line | Count | Source | 694 | 32 | fn overflow_digits(radix: u32) -> usize { | 695 | | // this is heavily optimized for base10 and it's a way under estimate | 696 | | // that said, it's fast and works. | 697 | 32 | if radix <= 16 { | 698 | 32 | mem::size_of::<Self>() * 2 - Self::IS_SIGNED as usize | 699 | | } else { | 700 | | // way under approximation but always works and is fast | 701 | 0 | mem::size_of::<Self>() | 702 | | } | 703 | 32 | } |
<i16 as lexical_util::num::Integer>::overflow_digits Line | Count | Source | 694 | 33 | fn overflow_digits(radix: u32) -> usize { | 695 | | // this is heavily optimized for base10 and it's a way under estimate | 696 | | // that said, it's fast and works. | 697 | 33 | if radix <= 16 { | 698 | 33 | mem::size_of::<Self>() * 2 - Self::IS_SIGNED as usize | 699 | | } else { | 700 | | // way under approximation but always works and is fast | 701 | 0 | mem::size_of::<Self>() | 702 | | } | 703 | 33 | } |
<u16 as lexical_util::num::Integer>::overflow_digits Line | Count | Source | 694 | 15 | fn overflow_digits(radix: u32) -> usize { | 695 | | // this is heavily optimized for base10 and it's a way under estimate | 696 | | // that said, it's fast and works. | 697 | 15 | if radix <= 16 { | 698 | 15 | mem::size_of::<Self>() * 2 - Self::IS_SIGNED as usize | 699 | | } else { | 700 | | // way under approximation but always works and is fast | 701 | 0 | mem::size_of::<Self>() | 702 | | } | 703 | 15 | } |
<isize as lexical_util::num::Integer>::overflow_digits Line | Count | Source | 694 | 31 | fn overflow_digits(radix: u32) -> usize { | 695 | | // this is heavily optimized for base10 and it's a way under estimate | 696 | | // that said, it's fast and works. | 697 | 31 | if radix <= 16 { | 698 | 31 | mem::size_of::<Self>() * 2 - Self::IS_SIGNED as usize | 699 | | } else { | 700 | | // way under approximation but always works and is fast | 701 | 0 | mem::size_of::<Self>() | 702 | | } | 703 | 31 | } |
<i64 as lexical_util::num::Integer>::overflow_digits Line | Count | Source | 694 | 30 | fn overflow_digits(radix: u32) -> usize { | 695 | | // this is heavily optimized for base10 and it's a way under estimate | 696 | | // that said, it's fast and works. | 697 | 30 | if radix <= 16 { | 698 | 30 | mem::size_of::<Self>() * 2 - Self::IS_SIGNED as usize | 699 | | } else { | 700 | | // way under approximation but always works and is fast | 701 | 0 | mem::size_of::<Self>() | 702 | | } | 703 | 30 | } |
<u128 as lexical_util::num::Integer>::overflow_digits Line | Count | Source | 694 | 12 | fn overflow_digits(radix: u32) -> usize { | 695 | | // this is heavily optimized for base10 and it's a way under estimate | 696 | | // that said, it's fast and works. | 697 | 12 | if radix <= 16 { | 698 | 12 | mem::size_of::<Self>() * 2 - Self::IS_SIGNED as usize | 699 | | } else { | 700 | | // way under approximation but always works and is fast | 701 | 0 | mem::size_of::<Self>() | 702 | | } | 703 | 12 | } |
|
704 | | } |
705 | | |
706 | | macro_rules! integer_impl { |
707 | | ($($t:tt)*) => ($( |
708 | | impl Integer for $t { |
709 | | const ZERO: $t = 0; |
710 | | const ONE: $t = 1; |
711 | | const TWO: $t = 2; |
712 | | const MAX: $t = $t::MAX; |
713 | | const MIN: $t = $t::MIN; |
714 | | const BITS: usize = $t::BITS as usize; |
715 | | |
716 | | #[inline(always)] |
717 | 2.66k | fn leading_zeros(self) -> u32 { |
718 | 2.66k | $t::leading_zeros(self) |
719 | 2.66k | } <u32 as lexical_util::num::Integer>::leading_zeros Line | Count | Source | 717 | 642 | fn leading_zeros(self) -> u32 { | 718 | 642 | $t::leading_zeros(self) | 719 | 642 | } |
<u64 as lexical_util::num::Integer>::leading_zeros Line | Count | Source | 717 | 2.02k | fn leading_zeros(self) -> u32 { | 718 | 2.02k | $t::leading_zeros(self) | 719 | 2.02k | } |
|
720 | | |
721 | | #[inline(always)] |
722 | | fn trailing_zeros(self) -> u32 { |
723 | | $t::trailing_zeros(self) |
724 | | } |
725 | | |
726 | | #[inline(always)] |
727 | 2 | fn checked_add(self, i: Self) -> Option<Self> { |
728 | 2 | $t::checked_add(self, i) |
729 | 2 | } Unexecuted instantiation: <u64 as lexical_util::num::Integer>::checked_add Unexecuted instantiation: <usize as lexical_util::num::Integer>::checked_add Unexecuted instantiation: <i8 as lexical_util::num::Integer>::checked_add <u32 as lexical_util::num::Integer>::checked_add Line | Count | Source | 727 | 2 | fn checked_add(self, i: Self) -> Option<Self> { | 728 | 2 | $t::checked_add(self, i) | 729 | 2 | } |
Unexecuted instantiation: <i128 as lexical_util::num::Integer>::checked_add Unexecuted instantiation: <u8 as lexical_util::num::Integer>::checked_add Unexecuted instantiation: <i32 as lexical_util::num::Integer>::checked_add Unexecuted instantiation: <i16 as lexical_util::num::Integer>::checked_add Unexecuted instantiation: <u16 as lexical_util::num::Integer>::checked_add Unexecuted instantiation: <isize as lexical_util::num::Integer>::checked_add Unexecuted instantiation: <i64 as lexical_util::num::Integer>::checked_add Unexecuted instantiation: <u128 as lexical_util::num::Integer>::checked_add |
730 | | |
731 | | #[inline(always)] |
732 | 0 | fn checked_sub(self, i: Self) -> Option<Self> { |
733 | 0 | $t::checked_sub(self, i) |
734 | 0 | } Unexecuted instantiation: <u64 as lexical_util::num::Integer>::checked_sub Unexecuted instantiation: <usize as lexical_util::num::Integer>::checked_sub Unexecuted instantiation: <i8 as lexical_util::num::Integer>::checked_sub Unexecuted instantiation: <u32 as lexical_util::num::Integer>::checked_sub Unexecuted instantiation: <i128 as lexical_util::num::Integer>::checked_sub Unexecuted instantiation: <u8 as lexical_util::num::Integer>::checked_sub Unexecuted instantiation: <i32 as lexical_util::num::Integer>::checked_sub Unexecuted instantiation: <i16 as lexical_util::num::Integer>::checked_sub Unexecuted instantiation: <u16 as lexical_util::num::Integer>::checked_sub Unexecuted instantiation: <isize as lexical_util::num::Integer>::checked_sub Unexecuted instantiation: <i64 as lexical_util::num::Integer>::checked_sub Unexecuted instantiation: <u128 as lexical_util::num::Integer>::checked_sub |
735 | | |
736 | | #[inline(always)] |
737 | 2 | fn checked_mul(self, i: Self) -> Option<Self> { |
738 | 2 | $t::checked_mul(self, i) |
739 | 2 | } Unexecuted instantiation: <u64 as lexical_util::num::Integer>::checked_mul Unexecuted instantiation: <usize as lexical_util::num::Integer>::checked_mul Unexecuted instantiation: <i8 as lexical_util::num::Integer>::checked_mul <u32 as lexical_util::num::Integer>::checked_mul Line | Count | Source | 737 | 2 | fn checked_mul(self, i: Self) -> Option<Self> { | 738 | 2 | $t::checked_mul(self, i) | 739 | 2 | } |
Unexecuted instantiation: <i128 as lexical_util::num::Integer>::checked_mul Unexecuted instantiation: <u8 as lexical_util::num::Integer>::checked_mul Unexecuted instantiation: <i32 as lexical_util::num::Integer>::checked_mul Unexecuted instantiation: <i16 as lexical_util::num::Integer>::checked_mul Unexecuted instantiation: <u16 as lexical_util::num::Integer>::checked_mul Unexecuted instantiation: <isize as lexical_util::num::Integer>::checked_mul Unexecuted instantiation: <i64 as lexical_util::num::Integer>::checked_mul Unexecuted instantiation: <u128 as lexical_util::num::Integer>::checked_mul |
740 | | |
741 | | #[inline(always)] |
742 | | fn overflowing_add(self, i: Self) -> (Self, bool) { |
743 | | $t::overflowing_add(self, i) |
744 | | } |
745 | | |
746 | | #[inline(always)] |
747 | | fn overflowing_sub(self, i: Self) -> (Self, bool) { |
748 | | $t::overflowing_sub(self, i) |
749 | | } |
750 | | |
751 | | #[inline(always)] |
752 | | fn overflowing_mul(self, i: Self) -> (Self, bool) { |
753 | | $t::overflowing_mul(self, i) |
754 | | } |
755 | | |
756 | | #[inline(always)] |
757 | 18 | fn wrapping_add(self, i: Self) -> Self { |
758 | 18 | $t::wrapping_add(self, i) |
759 | 18 | } Unexecuted instantiation: <u64 as lexical_util::num::Integer>::wrapping_add <usize as lexical_util::num::Integer>::wrapping_add Line | Count | Source | 757 | 2 | fn wrapping_add(self, i: Self) -> Self { | 758 | 2 | $t::wrapping_add(self, i) | 759 | 2 | } |
<i8 as lexical_util::num::Integer>::wrapping_add Line | Count | Source | 757 | 2 | fn wrapping_add(self, i: Self) -> Self { | 758 | 2 | $t::wrapping_add(self, i) | 759 | 2 | } |
<u32 as lexical_util::num::Integer>::wrapping_add Line | Count | Source | 757 | 9 | fn wrapping_add(self, i: Self) -> Self { | 758 | 9 | $t::wrapping_add(self, i) | 759 | 9 | } |
Unexecuted instantiation: <i128 as lexical_util::num::Integer>::wrapping_add Unexecuted instantiation: <u8 as lexical_util::num::Integer>::wrapping_add <i32 as lexical_util::num::Integer>::wrapping_add Line | Count | Source | 757 | 3 | fn wrapping_add(self, i: Self) -> Self { | 758 | 3 | $t::wrapping_add(self, i) | 759 | 3 | } |
<i16 as lexical_util::num::Integer>::wrapping_add Line | Count | Source | 757 | 1 | fn wrapping_add(self, i: Self) -> Self { | 758 | 1 | $t::wrapping_add(self, i) | 759 | 1 | } |
<u16 as lexical_util::num::Integer>::wrapping_add Line | Count | Source | 757 | 1 | fn wrapping_add(self, i: Self) -> Self { | 758 | 1 | $t::wrapping_add(self, i) | 759 | 1 | } |
Unexecuted instantiation: <isize as lexical_util::num::Integer>::wrapping_add Unexecuted instantiation: <i64 as lexical_util::num::Integer>::wrapping_add Unexecuted instantiation: <u128 as lexical_util::num::Integer>::wrapping_add |
760 | | |
761 | | #[inline(always)] |
762 | 0 | fn wrapping_sub(self, i: Self) -> Self { |
763 | 0 | $t::wrapping_sub(self, i) |
764 | 0 | } Unexecuted instantiation: <u64 as lexical_util::num::Integer>::wrapping_sub Unexecuted instantiation: <usize as lexical_util::num::Integer>::wrapping_sub Unexecuted instantiation: <i8 as lexical_util::num::Integer>::wrapping_sub Unexecuted instantiation: <u32 as lexical_util::num::Integer>::wrapping_sub Unexecuted instantiation: <i128 as lexical_util::num::Integer>::wrapping_sub Unexecuted instantiation: <u8 as lexical_util::num::Integer>::wrapping_sub Unexecuted instantiation: <i32 as lexical_util::num::Integer>::wrapping_sub Unexecuted instantiation: <i16 as lexical_util::num::Integer>::wrapping_sub Unexecuted instantiation: <u16 as lexical_util::num::Integer>::wrapping_sub Unexecuted instantiation: <isize as lexical_util::num::Integer>::wrapping_sub Unexecuted instantiation: <i64 as lexical_util::num::Integer>::wrapping_sub Unexecuted instantiation: <u128 as lexical_util::num::Integer>::wrapping_sub |
765 | | |
766 | | #[inline(always)] |
767 | 18 | fn wrapping_mul(self, i: Self) -> Self { |
768 | 18 | $t::wrapping_mul(self, i) |
769 | 18 | } Unexecuted instantiation: <u64 as lexical_util::num::Integer>::wrapping_mul <usize as lexical_util::num::Integer>::wrapping_mul Line | Count | Source | 767 | 2 | fn wrapping_mul(self, i: Self) -> Self { | 768 | 2 | $t::wrapping_mul(self, i) | 769 | 2 | } |
<i8 as lexical_util::num::Integer>::wrapping_mul Line | Count | Source | 767 | 2 | fn wrapping_mul(self, i: Self) -> Self { | 768 | 2 | $t::wrapping_mul(self, i) | 769 | 2 | } |
<u32 as lexical_util::num::Integer>::wrapping_mul Line | Count | Source | 767 | 9 | fn wrapping_mul(self, i: Self) -> Self { | 768 | 9 | $t::wrapping_mul(self, i) | 769 | 9 | } |
Unexecuted instantiation: <i128 as lexical_util::num::Integer>::wrapping_mul Unexecuted instantiation: <u8 as lexical_util::num::Integer>::wrapping_mul <i32 as lexical_util::num::Integer>::wrapping_mul Line | Count | Source | 767 | 3 | fn wrapping_mul(self, i: Self) -> Self { | 768 | 3 | $t::wrapping_mul(self, i) | 769 | 3 | } |
<i16 as lexical_util::num::Integer>::wrapping_mul Line | Count | Source | 767 | 1 | fn wrapping_mul(self, i: Self) -> Self { | 768 | 1 | $t::wrapping_mul(self, i) | 769 | 1 | } |
<u16 as lexical_util::num::Integer>::wrapping_mul Line | Count | Source | 767 | 1 | fn wrapping_mul(self, i: Self) -> Self { | 768 | 1 | $t::wrapping_mul(self, i) | 769 | 1 | } |
Unexecuted instantiation: <isize as lexical_util::num::Integer>::wrapping_mul Unexecuted instantiation: <i64 as lexical_util::num::Integer>::wrapping_mul Unexecuted instantiation: <u128 as lexical_util::num::Integer>::wrapping_mul |
770 | | |
771 | | #[inline(always)] |
772 | 128 | fn wrapping_neg(self) -> Self { |
773 | 128 | $t::wrapping_neg(self) |
774 | 128 | } <i16 as lexical_util::num::Integer>::wrapping_neg Line | Count | Source | 772 | 17 | fn wrapping_neg(self) -> Self { | 773 | 17 | $t::wrapping_neg(self) | 774 | 17 | } |
<i128 as lexical_util::num::Integer>::wrapping_neg Line | Count | Source | 772 | 58 | fn wrapping_neg(self) -> Self { | 773 | 58 | $t::wrapping_neg(self) | 774 | 58 | } |
<i8 as lexical_util::num::Integer>::wrapping_neg Line | Count | Source | 772 | 18 | fn wrapping_neg(self) -> Self { | 773 | 18 | $t::wrapping_neg(self) | 774 | 18 | } |
<isize as lexical_util::num::Integer>::wrapping_neg Line | Count | Source | 772 | 13 | fn wrapping_neg(self) -> Self { | 773 | 13 | $t::wrapping_neg(self) | 774 | 13 | } |
<i64 as lexical_util::num::Integer>::wrapping_neg Line | Count | Source | 772 | 8 | fn wrapping_neg(self) -> Self { | 773 | 8 | $t::wrapping_neg(self) | 774 | 8 | } |
<i32 as lexical_util::num::Integer>::wrapping_neg Line | Count | Source | 772 | 14 | fn wrapping_neg(self) -> Self { | 773 | 14 | $t::wrapping_neg(self) | 774 | 14 | } |
|
775 | | |
776 | | #[inline(always)] |
777 | | fn pow(self, exp: u32) -> Self { |
778 | | Self::pow(self, exp) |
779 | | } |
780 | | |
781 | | #[inline(always)] |
782 | | fn checked_pow(self, exp: u32) -> Option<Self> { |
783 | | Self::checked_pow(self, exp) |
784 | | } |
785 | | |
786 | | #[inline(always)] |
787 | | fn overflowing_pow(self, exp: u32) -> (Self, bool) { |
788 | | Self::overflowing_pow(self, exp) |
789 | | } |
790 | | |
791 | | #[inline(always)] |
792 | | fn saturating_add(self, i: Self) -> Self { |
793 | | $t::saturating_add(self, i) |
794 | | } |
795 | | |
796 | | #[inline(always)] |
797 | | fn saturating_sub(self, i: Self) -> Self { |
798 | | $t::saturating_sub(self, i) |
799 | | } |
800 | | |
801 | | #[inline(always)] |
802 | | fn saturating_mul(self, i: Self) -> Self { |
803 | | $t::saturating_mul(self, i) |
804 | | } |
805 | | } |
806 | | )*) |
807 | | } |
808 | | |
809 | | integer_impl! { u8 u16 u32 u64 u128 i8 i16 i32 i64 i128 usize isize } |
810 | | |
811 | | // SIGNED INTEGER |
812 | | // -------------- |
813 | | |
814 | | /// The trait for types that support [`signed`] integral operations, that is, |
815 | | /// they can hold negative numbers. |
816 | | /// |
817 | | /// [`signed`]: https://en.wikipedia.org/wiki/Integer_(computer_science)#Value_and_representation |
818 | | pub trait SignedInteger: Integer + ops::Neg<Output = Self> {} |
819 | | |
820 | | macro_rules! signed_integer_impl { |
821 | | ($($t:tt)*) => ($( |
822 | | impl SignedInteger for $t {} |
823 | | )*) |
824 | | } |
825 | | |
826 | | signed_integer_impl! { i8 i16 i32 i64 i128 isize } |
827 | | |
828 | | // UNSIGNED INTEGER |
829 | | // ---------------- |
830 | | |
831 | | /// The trait for types that support [`unsigned`] integral operations, that is, |
832 | | /// they can only hold positive numbers. |
833 | | /// |
834 | | /// [`unsigned`]: https://en.wikipedia.org/wiki/Integer_(computer_science)#Value_and_representation |
835 | | pub trait UnsignedInteger: Integer {} |
836 | | |
837 | | macro_rules! unsigned_integer_impl { |
838 | | ($($t:ty)*) => ($( |
839 | | impl UnsignedInteger for $t {} |
840 | | )*) |
841 | | } |
842 | | |
843 | | unsigned_integer_impl! { u8 u16 u32 u64 u128 usize } |
844 | | |
845 | | // FLOAT |
846 | | // ----- |
847 | | |
848 | | /// The trait for floating-point [`numbers`][`floats`]. |
849 | | /// |
850 | | /// Floating-point numbers are numbers that may contain a fraction |
851 | | /// and are stored internally as the significant digits and an |
852 | | /// exponent of base 2. |
853 | | /// |
854 | | /// [`floats`]: https://en.wikipedia.org/wiki/Floating-point_arithmetic |
855 | | #[cfg(any(feature = "parse-floats", feature = "write-floats"))] |
856 | | pub trait Float: Number + ops::Neg<Output = Self> { |
857 | | /// Unsigned type of the same size. |
858 | | type Unsigned: UnsignedInteger; |
859 | | |
860 | | // CONSTANTS |
861 | | |
862 | | /// A value equal to `0`. |
863 | | const ZERO: Self; |
864 | | |
865 | | /// A value equal to `1`. |
866 | | const ONE: Self; |
867 | | |
868 | | /// A value equal to `2`. |
869 | | const TWO: Self; |
870 | | |
871 | | /// Largest finite value. |
872 | | /// |
873 | | /// See [`f64::MAX`]. |
874 | | const MAX: Self; |
875 | | |
876 | | /// Smallest finite value. |
877 | | /// |
878 | | /// See [`f64::MIN`]. |
879 | | const MIN: Self; |
880 | | |
881 | | /// Infinity (`∞`). |
882 | | /// |
883 | | /// See [`f64::INFINITY`]. |
884 | | const INFINITY: Self; |
885 | | |
886 | | /// Negative infinity (`−∞`). |
887 | | /// |
888 | | /// See [`f64::NEG_INFINITY`]. |
889 | | const NEG_INFINITY: Self; |
890 | | |
891 | | /// Not a Number (NaN). |
892 | | /// |
893 | | /// See [`f64::NAN`]. |
894 | | const NAN: Self; |
895 | | |
896 | | /// The size of this float type in bits. |
897 | | /// |
898 | | /// Analogous to [`u32::BITS`]. |
899 | | const BITS: usize; |
900 | | |
901 | | /// Bitmask to extract the sign from the float. |
902 | | const SIGN_MASK: Self::Unsigned; |
903 | | |
904 | | /// Bitmask to extract the biased exponent, including the hidden bit. |
905 | | const EXPONENT_MASK: Self::Unsigned; |
906 | | |
907 | | /// Bitmask to extract the hidden bit in the exponent, which is an |
908 | | /// implicit 1 in the significant digits. |
909 | | const HIDDEN_BIT_MASK: Self::Unsigned; |
910 | | |
911 | | /// Bitmask to extract the mantissa (significant digits), excluding |
912 | | /// the hidden bit. |
913 | | const MANTISSA_MASK: Self::Unsigned; |
914 | | |
915 | | /// Mask to determine if a full-carry occurred (1 in bit above hidden bit). |
916 | | const CARRY_MASK: Self::Unsigned; |
917 | | |
918 | | // PROPERTIES |
919 | | |
920 | | // The following constants can be calculated as follows: |
921 | | // - `INFINITY_BITS`: EXPONENT_MASK |
922 | | // - `NEGATIVE_INFINITY_BITS`: INFINITY_BITS | SIGN_MASK |
923 | | // - `EXPONENT_BIAS`: `2^(EXPONENT_SIZE-1) - 1 + MANTISSA_SIZE` |
924 | | // - `DENORMAL_EXPONENT`: `1 - EXPONENT_BIAS` |
925 | | // - `MAX_EXPONENT`: `2^EXPONENT_SIZE - 1 - EXPONENT_BIAS` |
926 | | |
927 | | /// Positive infinity as bits. |
928 | | const INFINITY_BITS: Self::Unsigned; |
929 | | |
930 | | /// Positive infinity as bits. |
931 | | const NEGATIVE_INFINITY_BITS: Self::Unsigned; |
932 | | |
933 | | /// The number of bits in the exponent. |
934 | | const EXPONENT_SIZE: i32; |
935 | | |
936 | | /// Size of the significand (mantissa) without the hidden bit. |
937 | | const MANTISSA_SIZE: i32; |
938 | | |
939 | | /// Bias of the exponent. See [`exponent bias`]. |
940 | | /// |
941 | | /// [`exponent bias`]: https://en.wikipedia.org/wiki/Exponent_bias |
942 | | const EXPONENT_BIAS: i32; |
943 | | |
944 | | /// Exponent portion of a [`denormal`] float. |
945 | | /// |
946 | | /// [`denormal`]: https://en.wikipedia.org/wiki/Subnormal_number |
947 | | const DENORMAL_EXPONENT: i32; |
948 | | |
949 | | /// Maximum (unbiased) exponent value in the float. |
950 | | const MAX_EXPONENT: i32; |
951 | | |
952 | | // FUNCTIONS (INHERITED) |
953 | | |
954 | | // Re-export the to and from bits methods. |
955 | | |
956 | | /// Raw transmutation to the unsigned integral type. |
957 | | /// |
958 | | /// See [`f64::to_bits`]. |
959 | | fn to_bits(self) -> Self::Unsigned; |
960 | | |
961 | | /// Raw transmutation from the unsigned integral type. |
962 | | /// |
963 | | /// See [`f64::from_bits`]. |
964 | | fn from_bits(u: Self::Unsigned) -> Self; |
965 | | |
966 | | /// Returns the natural logarithm of the number. |
967 | | /// |
968 | | /// See [`f64::ln`]. |
969 | | fn ln(self) -> Self; |
970 | | |
971 | | /// Returns the largest integer less than or equal to `self`. |
972 | | /// |
973 | | /// See [`f64::floor`]. |
974 | | fn floor(self) -> Self; |
975 | | |
976 | | /// Returns true if `self` has a positive sign, including `+0.0`, |
977 | | /// NaNs with positive sign bit and positive infinity. |
978 | | /// |
979 | | /// See [`f64::is_sign_positive`]. |
980 | | fn is_sign_positive(self) -> bool; |
981 | | |
982 | | /// Returns true if `self` has a negative sign, including `-0.0`, |
983 | | /// NaNs with negative sign bit and negative infinity. |
984 | | /// |
985 | | /// See [`f64::is_sign_negative`]. |
986 | | fn is_sign_negative(self) -> bool; |
987 | | |
988 | | /// Returns true if the float is [`denormal`]. |
989 | | /// |
990 | | /// Denormal (subnormal) numbers fall below the range of numbers |
991 | | /// that can be stored as `mantissa * 2^exp`, and therefore |
992 | | /// always have the minimum exponent. |
993 | | /// |
994 | | /// [`denormal`]: https://en.wikipedia.org/wiki/Subnormal_number |
995 | | #[inline(always)] |
996 | 9.12k | fn is_denormal(self) -> bool { |
997 | 9.12k | self.to_bits() & Self::EXPONENT_MASK == Self::Unsigned::ZERO |
998 | 9.12k | } <f32 as lexical_util::num::Float>::is_denormal Line | Count | Source | 996 | 1.22k | fn is_denormal(self) -> bool { | 997 | 1.22k | self.to_bits() & Self::EXPONENT_MASK == Self::Unsigned::ZERO | 998 | 1.22k | } |
<f64 as lexical_util::num::Float>::is_denormal Line | Count | Source | 996 | 3.96k | fn is_denormal(self) -> bool { | 997 | 3.96k | self.to_bits() & Self::EXPONENT_MASK == Self::Unsigned::ZERO | 998 | 3.96k | } |
<f32 as lexical_util::num::Float>::is_denormal Line | Count | Source | 996 | 1.98k | fn is_denormal(self) -> bool { | 997 | 1.98k | self.to_bits() & Self::EXPONENT_MASK == Self::Unsigned::ZERO | 998 | 1.98k | } |
<f64 as lexical_util::num::Float>::is_denormal Line | Count | Source | 996 | 1.94k | fn is_denormal(self) -> bool { | 997 | 1.94k | self.to_bits() & Self::EXPONENT_MASK == Self::Unsigned::ZERO | 998 | 1.94k | } |
|
999 | | |
1000 | | /// Returns true if the float is NaN, positive infinity, or negative |
1001 | | /// infinity. |
1002 | | #[inline(always)] |
1003 | 4.16k | fn is_special(self) -> bool { |
1004 | 4.16k | self.to_bits() & Self::EXPONENT_MASK == Self::EXPONENT_MASK |
1005 | 4.16k | } <f32 as lexical_util::num::Float>::is_special Line | Count | Source | 1003 | 1.08k | fn is_special(self) -> bool { | 1004 | 1.08k | self.to_bits() & Self::EXPONENT_MASK == Self::EXPONENT_MASK | 1005 | 1.08k | } |
<f64 as lexical_util::num::Float>::is_special Line | Count | Source | 1003 | 3.08k | fn is_special(self) -> bool { | 1004 | 3.08k | self.to_bits() & Self::EXPONENT_MASK == Self::EXPONENT_MASK | 1005 | 3.08k | } |
|
1006 | | |
1007 | | /// Returns true if the float is NaN. |
1008 | | #[inline(always)] |
1009 | 1.36k | fn is_nan(self) -> bool { |
1010 | 1.36k | self.is_special() && (self.to_bits() & Self::MANTISSA_MASK) != Self::Unsigned::ZERO |
1011 | 1.36k | } <f32 as lexical_util::num::Float>::is_nan Line | Count | Source | 1009 | 393 | fn is_nan(self) -> bool { | 1010 | 393 | self.is_special() && (self.to_bits() & Self::MANTISSA_MASK) != Self::Unsigned::ZERO | 1011 | 393 | } |
<f64 as lexical_util::num::Float>::is_nan Line | Count | Source | 1009 | 975 | fn is_nan(self) -> bool { | 1010 | 975 | self.is_special() && (self.to_bits() & Self::MANTISSA_MASK) != Self::Unsigned::ZERO | 1011 | 975 | } |
|
1012 | | |
1013 | | /// Returns true if the float is positive or negative infinity. |
1014 | | #[inline(always)] |
1015 | | fn is_inf(self) -> bool { |
1016 | | self.is_special() && (self.to_bits() & Self::MANTISSA_MASK) == Self::Unsigned::ZERO |
1017 | | } |
1018 | | |
1019 | | /// Returns true if the float's least-significant mantissa bit is odd. |
1020 | | #[inline(always)] |
1021 | | fn is_odd(self) -> bool { |
1022 | | self.to_bits().is_odd() |
1023 | | } |
1024 | | |
1025 | | /// Returns true if the float's least-significant mantissa bit is even. |
1026 | | #[inline(always)] |
1027 | | fn is_even(self) -> bool { |
1028 | | !self.is_odd() |
1029 | | } |
1030 | | |
1031 | | /// Returns true if the float needs a negative sign when serializing it. |
1032 | | /// |
1033 | | /// This is true if it's `-0.0` or it's below 0 and not NaN. But inf values |
1034 | | /// need the sign. |
1035 | | #[inline(always)] |
1036 | 2.80k | fn needs_negative_sign(self) -> bool { |
1037 | 2.80k | self.is_sign_negative() && !self.is_nan() |
1038 | 2.80k | } <f32 as lexical_util::num::Float>::needs_negative_sign Line | Count | Source | 1036 | 692 | fn needs_negative_sign(self) -> bool { | 1037 | 692 | self.is_sign_negative() && !self.is_nan() | 1038 | 692 | } |
<f64 as lexical_util::num::Float>::needs_negative_sign Line | Count | Source | 1036 | 2.10k | fn needs_negative_sign(self) -> bool { | 1037 | 2.10k | self.is_sign_negative() && !self.is_nan() | 1038 | 2.10k | } |
|
1039 | | |
1040 | | /// Get the unbiased exponent component from the float. |
1041 | | #[inline(always)] |
1042 | 4.63k | fn exponent(self) -> i32 { |
1043 | 4.63k | if self.is_denormal() { |
1044 | 417 | return Self::DENORMAL_EXPONENT; |
1045 | 4.21k | } |
1046 | | |
1047 | 4.21k | let bits = self.to_bits(); |
1048 | 4.21k | let biased_e = i32::as_cast((bits & Self::EXPONENT_MASK) >> Self::MANTISSA_SIZE).as_i32(); |
1049 | 4.21k | biased_e - Self::EXPONENT_BIAS |
1050 | 4.63k | } <f32 as lexical_util::num::Float>::exponent Line | Count | Source | 1042 | 639 | fn exponent(self) -> i32 { | 1043 | 639 | if self.is_denormal() { | 1044 | 70 | return Self::DENORMAL_EXPONENT; | 1045 | 569 | } | 1046 | | | 1047 | 569 | let bits = self.to_bits(); | 1048 | 569 | let biased_e = i32::as_cast((bits & Self::EXPONENT_MASK) >> Self::MANTISSA_SIZE).as_i32(); | 1049 | 569 | biased_e - Self::EXPONENT_BIAS | 1050 | 639 | } |
<f64 as lexical_util::num::Float>::exponent Line | Count | Source | 1042 | 2.02k | fn exponent(self) -> i32 { | 1043 | 2.02k | if self.is_denormal() { | 1044 | 244 | return Self::DENORMAL_EXPONENT; | 1045 | 1.78k | } | 1046 | | | 1047 | 1.78k | let bits = self.to_bits(); | 1048 | 1.78k | let biased_e = i32::as_cast((bits & Self::EXPONENT_MASK) >> Self::MANTISSA_SIZE).as_i32(); | 1049 | 1.78k | biased_e - Self::EXPONENT_BIAS | 1050 | 2.02k | } |
<f32 as lexical_util::num::Float>::exponent Line | Count | Source | 1042 | 992 | fn exponent(self) -> i32 { | 1043 | 992 | if self.is_denormal() { | 1044 | 0 | return Self::DENORMAL_EXPONENT; | 1045 | 992 | } | 1046 | | | 1047 | 992 | let bits = self.to_bits(); | 1048 | 992 | let biased_e = i32::as_cast((bits & Self::EXPONENT_MASK) >> Self::MANTISSA_SIZE).as_i32(); | 1049 | 992 | biased_e - Self::EXPONENT_BIAS | 1050 | 992 | } |
<f64 as lexical_util::num::Float>::exponent Line | Count | Source | 1042 | 973 | fn exponent(self) -> i32 { | 1043 | 973 | if self.is_denormal() { | 1044 | 103 | return Self::DENORMAL_EXPONENT; | 1045 | 870 | } | 1046 | | | 1047 | 870 | let bits = self.to_bits(); | 1048 | 870 | let biased_e = i32::as_cast((bits & Self::EXPONENT_MASK) >> Self::MANTISSA_SIZE).as_i32(); | 1049 | 870 | biased_e - Self::EXPONENT_BIAS | 1050 | 973 | } |
|
1051 | | |
1052 | | /// Get the mantissa (significand) component from float. |
1053 | | #[inline(always)] |
1054 | 4.49k | fn mantissa(self) -> Self::Unsigned { |
1055 | 4.49k | let bits = self.to_bits(); |
1056 | 4.49k | let s = bits & Self::MANTISSA_MASK; |
1057 | 4.49k | if !self.is_denormal() { |
1058 | 4.07k | s + Self::HIDDEN_BIT_MASK |
1059 | | } else { |
1060 | 417 | s |
1061 | | } |
1062 | 4.49k | } <f32 as lexical_util::num::Float>::mantissa Line | Count | Source | 1054 | 588 | fn mantissa(self) -> Self::Unsigned { | 1055 | 588 | let bits = self.to_bits(); | 1056 | 588 | let s = bits & Self::MANTISSA_MASK; | 1057 | 588 | if !self.is_denormal() { | 1058 | 518 | s + Self::HIDDEN_BIT_MASK | 1059 | | } else { | 1060 | 70 | s | 1061 | | } | 1062 | 588 | } |
<f64 as lexical_util::num::Float>::mantissa Line | Count | Source | 1054 | 1.94k | fn mantissa(self) -> Self::Unsigned { | 1055 | 1.94k | let bits = self.to_bits(); | 1056 | 1.94k | let s = bits & Self::MANTISSA_MASK; | 1057 | 1.94k | if !self.is_denormal() { | 1058 | 1.69k | s + Self::HIDDEN_BIT_MASK | 1059 | | } else { | 1060 | 244 | s | 1061 | | } | 1062 | 1.94k | } |
<f32 as lexical_util::num::Float>::mantissa Line | Count | Source | 1054 | 992 | fn mantissa(self) -> Self::Unsigned { | 1055 | 992 | let bits = self.to_bits(); | 1056 | 992 | let s = bits & Self::MANTISSA_MASK; | 1057 | 992 | if !self.is_denormal() { | 1058 | 992 | s + Self::HIDDEN_BIT_MASK | 1059 | | } else { | 1060 | 0 | s | 1061 | | } | 1062 | 992 | } |
<f64 as lexical_util::num::Float>::mantissa Line | Count | Source | 1054 | 973 | fn mantissa(self) -> Self::Unsigned { | 1055 | 973 | let bits = self.to_bits(); | 1056 | 973 | let s = bits & Self::MANTISSA_MASK; | 1057 | 973 | if !self.is_denormal() { | 1058 | 870 | s + Self::HIDDEN_BIT_MASK | 1059 | | } else { | 1060 | 103 | s | 1061 | | } | 1062 | 973 | } |
|
1063 | | |
1064 | | /// Get next greater float. |
1065 | | /// |
1066 | | /// # Examples |
1067 | | /// |
1068 | | /// ```rust |
1069 | | /// use lexical_util::num::Float; |
1070 | | /// |
1071 | | /// assert_eq!(1f32.next(), 1.0000001); |
1072 | | /// assert_eq!((-0.0f32).next(), 0.0); // +0.0 |
1073 | | /// assert_eq!(0f32.next(), 1e-45); |
1074 | | /// ``` |
1075 | | #[inline(always)] |
1076 | | fn next(self) -> Self { |
1077 | | let bits = self.to_bits(); |
1078 | | if self.is_sign_negative() && self == Self::ZERO { |
1079 | | // -0.0 |
1080 | | Self::ZERO |
1081 | | } else if bits == Self::INFINITY_BITS { |
1082 | | Self::from_bits(Self::INFINITY_BITS) |
1083 | | } else if self.is_sign_negative() { |
1084 | | Self::from_bits(bits.saturating_sub(Self::Unsigned::ONE)) |
1085 | | } else { |
1086 | | Self::from_bits(bits.saturating_add(Self::Unsigned::ONE)) |
1087 | | } |
1088 | | } |
1089 | | |
1090 | | /// Get next greater float for a positive float. |
1091 | | /// |
1092 | | /// Value must be >= 0.0 and < INFINITY. |
1093 | | #[inline(always)] |
1094 | | fn next_positive(self) -> Self { |
1095 | | debug_assert!(self.is_sign_positive() && !self.is_inf()); |
1096 | | Self::from_bits(self.to_bits() + Self::Unsigned::ONE) |
1097 | | } |
1098 | | |
1099 | | /// Get previous greater float, such that `self.prev().next() == self`. |
1100 | | /// |
1101 | | /// # Examples |
1102 | | /// |
1103 | | /// ```rust |
1104 | | /// use lexical_util::num::Float; |
1105 | | /// |
1106 | | /// assert_eq!(1f32.prev(), 0.99999994); |
1107 | | /// assert_eq!(0.0f32.prev(), 0.0); // -0.0 |
1108 | | /// assert_eq!((-0.0f32).prev(), -1e-45); |
1109 | | /// ``` |
1110 | | #[inline(always)] |
1111 | | fn prev(self) -> Self { |
1112 | | let bits = self.to_bits(); |
1113 | | if self.is_sign_positive() && self == Self::ZERO { |
1114 | | // +0.0 |
1115 | | -Self::ZERO |
1116 | | } else if bits == Self::NEGATIVE_INFINITY_BITS { |
1117 | | Self::from_bits(Self::NEGATIVE_INFINITY_BITS) |
1118 | | } else if self.is_sign_negative() { |
1119 | | Self::from_bits(bits.saturating_add(Self::Unsigned::ONE)) |
1120 | | } else { |
1121 | | Self::from_bits(bits.saturating_sub(Self::Unsigned::ONE)) |
1122 | | } |
1123 | | } |
1124 | | |
1125 | | /// Get previous greater float for a positive float. |
1126 | | /// Value must be > 0.0. |
1127 | | #[inline(always)] |
1128 | | fn prev_positive(self) -> Self { |
1129 | | debug_assert!(self.is_sign_positive() && self != Self::ZERO); |
1130 | | Self::from_bits(self.to_bits() - Self::Unsigned::ONE) |
1131 | | } |
1132 | | |
1133 | | /// Round a positive number to even. |
1134 | | #[inline(always)] |
1135 | | fn round_positive_even(self) -> Self { |
1136 | | if self.mantissa().is_odd() { |
1137 | | self.next_positive() |
1138 | | } else { |
1139 | | self |
1140 | | } |
1141 | | } |
1142 | | |
1143 | | /// Get the max of two finite numbers. |
1144 | | /// |
1145 | | /// This assumes that both floats form a [`total ord`], |
1146 | | /// that is, `x < y` is always `y >= x`. Non-finite floats, |
1147 | | /// such as NaN, break this criteria, but finite floats enable |
1148 | | /// simpler (and faster) comparison criteria while remaining |
1149 | | /// accurate. |
1150 | | /// |
1151 | | /// [`total ord`]: https://doc.rust-lang.org/std/cmp/trait.Ord.html |
1152 | | #[inline(always)] |
1153 | | fn max_finite(self, f: Self) -> Self { |
1154 | | debug_assert!(!self.is_special() && !f.is_special(), "max_finite self={} f={}", self, f); |
1155 | | if self < f { |
1156 | | f |
1157 | | } else { |
1158 | | self |
1159 | | } |
1160 | | } |
1161 | | |
1162 | | /// Get the min of two finite numbers. |
1163 | | /// |
1164 | | /// This assumes that both floats form a [`total ord`], |
1165 | | /// that is, `x < y` is always `y >= x`. Non-finite floats, |
1166 | | /// such as NaN, break this criteria, but finite floats enable |
1167 | | /// simpler (and faster) comparison criteria while remaining |
1168 | | /// accurate. |
1169 | | /// |
1170 | | /// [`total ord`]: https://doc.rust-lang.org/std/cmp/trait.Ord.html |
1171 | | #[inline(always)] |
1172 | | fn min_finite(self, f: Self) -> Self { |
1173 | | debug_assert!(!self.is_special() && !f.is_special(), "min_finite self={} f={}", self, f); |
1174 | | if self < f { |
1175 | | self |
1176 | | } else { |
1177 | | f |
1178 | | } |
1179 | | } |
1180 | | } |
1181 | | |
1182 | | /// Define the float literals. |
1183 | | #[cfg(any(feature = "parse-floats", feature = "write-floats"))] |
1184 | | macro_rules! float_literals { |
1185 | | ($float:ty) => { |
1186 | | const ZERO: $float = 0.0; |
1187 | | const ONE: $float = 1.0; |
1188 | | const TWO: $float = 2.0; |
1189 | | const MAX: $float = <$float>::MAX; |
1190 | | const MIN: $float = <$float>::MIN; |
1191 | | const INFINITY: $float = <$float>::INFINITY; |
1192 | | const NEG_INFINITY: $float = <$float>::NEG_INFINITY; |
1193 | | const NAN: $float = <$float>::NAN; |
1194 | | const BITS: usize = mem::size_of::<$float>() * 8; |
1195 | | }; |
1196 | | } |
1197 | | |
1198 | | /// Define the float masks. |
1199 | | #[cfg(any(feature = "parse-floats", feature = "write-floats"))] |
1200 | | macro_rules! float_masks { |
1201 | | ( |
1202 | | float => |
1203 | | $float:ty,sign_mask => |
1204 | | $sign:literal,exponent_mask => |
1205 | | $exponent:literal,hidden_bit_mask => |
1206 | | $hidden:literal,mantissa_mask => |
1207 | | $mantissa:literal, |
1208 | | ) => { |
1209 | | const SIGN_MASK: <$float>::Unsigned = $sign; |
1210 | | const EXPONENT_MASK: <$float>::Unsigned = $exponent; |
1211 | | const HIDDEN_BIT_MASK: <$float>::Unsigned = $hidden; |
1212 | | const MANTISSA_MASK: <$float>::Unsigned = $mantissa; |
1213 | | // The carry mask is always 1 bit above the hidden bit. |
1214 | | const CARRY_MASK: <$float>::Unsigned = $hidden << 1; |
1215 | | // Infinity is always every exponent bit set. |
1216 | | const INFINITY_BITS: <$float>::Unsigned = $exponent; |
1217 | | // Negative infinity is just infinity + sign. |
1218 | | const NEGATIVE_INFINITY_BITS: <$float>::Unsigned = $exponent | $sign; |
1219 | | }; |
1220 | | } |
1221 | | |
1222 | | // Due to missing specifics or types for the following float types, |
1223 | | // `Float` is not yet fully implemented for: |
1224 | | // - f128 |
1225 | | |
1226 | | #[cfg(feature = "f16")] |
1227 | | macro_rules! float_one { |
1228 | | ($f:ident) => { |
1229 | | (($f::EXPONENT_BIAS - $f::MANTISSA_SIZE) as u16) << $f::MANTISSA_SIZE |
1230 | | }; |
1231 | | } |
1232 | | |
1233 | | #[cfg(feature = "f16")] |
1234 | | macro_rules! float_two { |
1235 | | ($f:ident) => { |
1236 | | (($f::EXPONENT_BIAS - $f::MANTISSA_SIZE + 1) as u16) << $f::MANTISSA_SIZE |
1237 | | }; |
1238 | | } |
1239 | | |
1240 | | #[cfg(feature = "f16")] |
1241 | | macro_rules! float_max { |
1242 | | ($f:ident) => { |
1243 | | ($f::EXPONENT_MASK ^ $f::HIDDEN_BIT_MASK) | $f::MANTISSA_MASK |
1244 | | }; |
1245 | | } |
1246 | | |
1247 | | #[cfg(feature = "f16")] |
1248 | | macro_rules! float_min { |
1249 | | ($f:ident) => { |
1250 | | $f::MAX.to_bits() | $f::SIGN_MASK |
1251 | | }; |
1252 | | } |
1253 | | |
1254 | | #[cfg(feature = "f16")] |
1255 | | macro_rules! float_nan { |
1256 | | ($f:ident) => { |
1257 | | $f::EXPONENT_MASK | ($f::HIDDEN_BIT_MASK >> 1) |
1258 | | }; |
1259 | | } |
1260 | | |
1261 | | #[cfg(feature = "f16")] |
1262 | | impl Float for f16 { |
1263 | | type Unsigned = u16; |
1264 | | |
1265 | | const ZERO: Self = Self::from_bits(0); |
1266 | | const ONE: Self = Self::from_bits(float_one!(Self)); |
1267 | | const TWO: Self = Self::from_bits(float_two!(Self)); |
1268 | | const MAX: Self = Self::from_bits(float_max!(Self)); |
1269 | | const MIN: Self = Self::from_bits(float_min!(Self)); |
1270 | | const INFINITY: Self = Self::from_bits(Self::INFINITY_BITS); |
1271 | | const NEG_INFINITY: Self = Self::from_bits(Self::NEGATIVE_INFINITY_BITS); |
1272 | | const NAN: Self = Self::from_bits(float_nan!(Self)); |
1273 | | const BITS: usize = mem::size_of::<Self>() * 8; |
1274 | | |
1275 | | float_masks!( |
1276 | | float => Self, |
1277 | | sign_mask => 0x8000, |
1278 | | exponent_mask => 0x7C00, |
1279 | | hidden_bit_mask => 0x0400, |
1280 | | mantissa_mask => 0x03FF, |
1281 | | ); |
1282 | | const EXPONENT_SIZE: i32 = 5; |
1283 | | const MANTISSA_SIZE: i32 = 10; |
1284 | | const EXPONENT_BIAS: i32 = 15 + Self::MANTISSA_SIZE; |
1285 | | const DENORMAL_EXPONENT: i32 = 1 - Self::EXPONENT_BIAS; |
1286 | | const MAX_EXPONENT: i32 = 0x1F - Self::EXPONENT_BIAS; |
1287 | | |
1288 | | #[inline(always)] |
1289 | | fn to_bits(self) -> u16 { |
1290 | | f16::to_bits(self) |
1291 | | } |
1292 | | |
1293 | | #[inline(always)] |
1294 | | fn from_bits(u: u16) -> f16 { |
1295 | | f16::from_bits(u) |
1296 | | } |
1297 | | |
1298 | | #[inline(always)] |
1299 | | fn ln(self) -> f16 { |
1300 | | f16::from_f32(self.as_f32().ln()) |
1301 | | } |
1302 | | |
1303 | | #[inline(always)] |
1304 | | fn floor(self) -> f16 { |
1305 | | f16::from_f32(self.as_f32().floor()) |
1306 | | } |
1307 | | |
1308 | | #[inline(always)] |
1309 | | fn is_sign_positive(self) -> bool { |
1310 | | self.to_bits() & Self::SIGN_MASK == 0 |
1311 | | } |
1312 | | |
1313 | | #[inline(always)] |
1314 | | fn is_sign_negative(self) -> bool { |
1315 | | !self.is_sign_positive() |
1316 | | } |
1317 | | } |
1318 | | |
1319 | | #[cfg(feature = "f16")] |
1320 | | impl Float for bf16 { |
1321 | | type Unsigned = u16; |
1322 | | |
1323 | | const ZERO: Self = Self::from_bits(0); |
1324 | | const ONE: Self = Self::from_bits(float_one!(Self)); |
1325 | | const TWO: Self = Self::from_bits(float_two!(Self)); |
1326 | | const MAX: Self = Self::from_bits(float_max!(Self)); |
1327 | | const MIN: Self = Self::from_bits(float_min!(Self)); |
1328 | | const INFINITY: Self = Self::from_bits(Self::INFINITY_BITS); |
1329 | | const NEG_INFINITY: Self = Self::from_bits(Self::NEGATIVE_INFINITY_BITS); |
1330 | | const NAN: Self = Self::from_bits(float_nan!(Self)); |
1331 | | const BITS: usize = mem::size_of::<Self>() * 8; |
1332 | | |
1333 | | float_masks!( |
1334 | | float => Self, |
1335 | | sign_mask => 0x8000, |
1336 | | exponent_mask => 0x7F80, |
1337 | | hidden_bit_mask => 0x0080, |
1338 | | mantissa_mask => 0x007F, |
1339 | | ); |
1340 | | const EXPONENT_SIZE: i32 = 8; |
1341 | | const MANTISSA_SIZE: i32 = 7; |
1342 | | const EXPONENT_BIAS: i32 = 127 + Self::MANTISSA_SIZE; |
1343 | | const DENORMAL_EXPONENT: i32 = 1 - Self::EXPONENT_BIAS; |
1344 | | const MAX_EXPONENT: i32 = 0xFF - Self::EXPONENT_BIAS; |
1345 | | |
1346 | | #[inline(always)] |
1347 | | fn to_bits(self) -> u16 { |
1348 | | bf16::to_bits(self) |
1349 | | } |
1350 | | |
1351 | | #[inline(always)] |
1352 | | fn from_bits(u: u16) -> bf16 { |
1353 | | bf16::from_bits(u) |
1354 | | } |
1355 | | |
1356 | | #[inline(always)] |
1357 | | fn ln(self) -> bf16 { |
1358 | | bf16::from_f32(self.as_f32().ln()) |
1359 | | } |
1360 | | |
1361 | | #[inline(always)] |
1362 | | fn floor(self) -> bf16 { |
1363 | | bf16::from_f32(self.as_f32().floor()) |
1364 | | } |
1365 | | |
1366 | | #[inline(always)] |
1367 | | fn is_sign_positive(self) -> bool { |
1368 | | self.to_bits() & Self::SIGN_MASK == 0 |
1369 | | } |
1370 | | |
1371 | | #[inline(always)] |
1372 | | fn is_sign_negative(self) -> bool { |
1373 | | !self.is_sign_positive() |
1374 | | } |
1375 | | } |
1376 | | |
1377 | | #[cfg(any(feature = "parse-floats", feature = "write-floats"))] |
1378 | | impl Float for f32 { |
1379 | | type Unsigned = u32; |
1380 | | float_literals!(f32); |
1381 | | float_masks!( |
1382 | | float => Self, |
1383 | | sign_mask => 0x80000000, |
1384 | | exponent_mask => 0x7F800000, |
1385 | | hidden_bit_mask => 0x00800000, |
1386 | | mantissa_mask => 0x007FFFFF, |
1387 | | ); |
1388 | | const EXPONENT_SIZE: i32 = 8; |
1389 | | const MANTISSA_SIZE: i32 = 23; |
1390 | | const EXPONENT_BIAS: i32 = 127 + Self::MANTISSA_SIZE; |
1391 | | const DENORMAL_EXPONENT: i32 = 1 - Self::EXPONENT_BIAS; |
1392 | | const MAX_EXPONENT: i32 = 0xFF - Self::EXPONENT_BIAS; |
1393 | | |
1394 | | #[inline(always)] |
1395 | 8.17k | fn to_bits(self) -> u32 { |
1396 | 8.17k | f32::to_bits(self) |
1397 | 8.17k | } |
1398 | | |
1399 | | #[inline(always)] |
1400 | 2.89k | fn from_bits(u: u32) -> f32 { |
1401 | 2.89k | f32::from_bits(u) |
1402 | 2.89k | } |
1403 | | |
1404 | | #[inline(always)] |
1405 | | fn ln(self) -> f32 { |
1406 | | #[cfg(feature = "std")] |
1407 | | return f32::ln(self); |
1408 | | |
1409 | | #[cfg(not(feature = "std"))] |
1410 | | return libm::logf(self); |
1411 | | } |
1412 | | |
1413 | | #[inline(always)] |
1414 | | fn floor(self) -> f32 { |
1415 | | #[cfg(feature = "std")] |
1416 | | return f32::floor(self); |
1417 | | |
1418 | | #[cfg(not(feature = "std"))] |
1419 | | return libm::floorf(self); |
1420 | | } |
1421 | | |
1422 | | #[inline(always)] |
1423 | | fn is_sign_positive(self) -> bool { |
1424 | | f32::is_sign_positive(self) |
1425 | | } |
1426 | | |
1427 | | #[inline(always)] |
1428 | 692 | fn is_sign_negative(self) -> bool { |
1429 | 692 | f32::is_sign_negative(self) |
1430 | 692 | } |
1431 | | } |
1432 | | |
1433 | | #[cfg(any(feature = "parse-floats", feature = "write-floats"))] |
1434 | | impl Float for f64 { |
1435 | | type Unsigned = u64; |
1436 | | float_literals!(f64); |
1437 | | float_masks!( |
1438 | | float => Self, |
1439 | | sign_mask => 0x8000000000000000, |
1440 | | exponent_mask => 0x7FF0000000000000, |
1441 | | hidden_bit_mask => 0x0010000000000000, |
1442 | | mantissa_mask => 0x000FFFFFFFFFFFFF, |
1443 | | ); |
1444 | | const EXPONENT_SIZE: i32 = 11; |
1445 | | const MANTISSA_SIZE: i32 = 52; |
1446 | | const EXPONENT_BIAS: i32 = 1023 + Self::MANTISSA_SIZE; |
1447 | | const DENORMAL_EXPONENT: i32 = 1 - Self::EXPONENT_BIAS; |
1448 | | const MAX_EXPONENT: i32 = 0x7FF - Self::EXPONENT_BIAS; |
1449 | | |
1450 | | #[inline(always)] |
1451 | 16.7k | fn to_bits(self) -> u64 { |
1452 | 16.7k | f64::to_bits(self) |
1453 | 16.7k | } |
1454 | | |
1455 | | #[inline(always)] |
1456 | 3.59k | fn from_bits(u: u64) -> f64 { |
1457 | 3.59k | f64::from_bits(u) |
1458 | 3.59k | } |
1459 | | |
1460 | | #[inline(always)] |
1461 | | fn ln(self) -> f64 { |
1462 | | #[cfg(feature = "std")] |
1463 | | return f64::ln(self); |
1464 | | |
1465 | | #[cfg(not(feature = "std"))] |
1466 | | return libm::logd(self); |
1467 | | } |
1468 | | |
1469 | | #[inline(always)] |
1470 | | fn floor(self) -> f64 { |
1471 | | #[cfg(feature = "std")] |
1472 | | return f64::floor(self); |
1473 | | |
1474 | | #[cfg(not(feature = "std"))] |
1475 | | return libm::floord(self); |
1476 | | } |
1477 | | |
1478 | | #[inline(always)] |
1479 | | fn is_sign_positive(self) -> bool { |
1480 | | f64::is_sign_positive(self) |
1481 | | } |
1482 | | |
1483 | | #[inline(always)] |
1484 | 2.10k | fn is_sign_negative(self) -> bool { |
1485 | 2.10k | f64::is_sign_negative(self) |
1486 | 2.10k | } |
1487 | | } |
1488 | | |
1489 | | // #[cfg(feature = "f128")] |
1490 | | // impl Float for f128 { |
1491 | | // type Unsigned = u128; |
1492 | | // float_literals!(f128); |
1493 | | // float_masks!( |
1494 | | // float => Self, |
1495 | | // sign_mask => 0x80000000000000000000000000000000, |
1496 | | // exponent_mask => 0x7FFF0000000000000000000000000000, |
1497 | | // hidden_bit_mask => 0x00010000000000000000000000000000, |
1498 | | // mantissa_mask => 0x0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF, |
1499 | | // ); |
1500 | | // const EXPONENT_SIZE: i32 = 15; |
1501 | | // const MANTISSA_SIZE: i32 = 112; |
1502 | | // const EXPONENT_BIAS: i32 = 16383 + Self::MANTISSA_SIZE; |
1503 | | // const DENORMAL_EXPONENT: i32 = 1 - Self::EXPONENT_BIAS; |
1504 | | // const MAX_EXPONENT: i32 = 0x7FFF - Self::EXPONENT_BIAS; |
1505 | | // } |