1 //! Utilities for Rust numbers.
2
3 // We have a lot of high-level casts that make the type-system work.
4 // Don't delete them, fake they're being used.
5 #![allow(dead_code)]
6
7 pub(crate) use crate::lib::{f32, f64, mem};
8 use crate::lib::{fmt, iter, ops};
9 use super::cast::{AsCast, TryCast};
10 use super::config::*;
11 use super::primitive::Primitive;
12
13 // NUMBER
14
15 /// Numerical type trait.
16 #[doc(hidden)]
17 pub trait Number:
18 Primitive +
19 // Iteration
20 iter::Product + iter::Sum +
21 // Operations
22 ops::Add<Output=Self> +
23 ops::AddAssign +
24 ops::Div<Output=Self> +
25 ops::DivAssign +
26 ops::Mul<Output=Self> +
27 ops::MulAssign +
28 ops::Rem<Output=Self> +
29 ops::RemAssign +
30 ops::Sub<Output=Self> +
31 ops::SubAssign
32 {
33 /// Maximum number of bytes required to serialize a number to string.
34 const FORMATTED_SIZE: usize;
35 /// Maximum number of bytes required to serialize a number to a decimal string.
36 const FORMATTED_SIZE_DECIMAL: usize;
37 /// If the type can hold a signed (negative) value.
38 const IS_SIGNED: bool;
39 }
40
41 macro_rules! number_impl {
42 ($($t:tt $radix_size:ident $decimal_size:ident $is_signed:expr ; )*) => ($(
43 impl Number for $t {
44 const FORMATTED_SIZE: usize = $radix_size;
45 const FORMATTED_SIZE_DECIMAL: usize = $decimal_size;
46 const IS_SIGNED: bool = $is_signed;
47 }
48 )*)
49 }
50
51 number_impl! {
52 u8 U8_FORMATTED_SIZE U8_FORMATTED_SIZE_DECIMAL false ;
53 u16 U16_FORMATTED_SIZE U16_FORMATTED_SIZE_DECIMAL false ;
54 u32 U32_FORMATTED_SIZE U32_FORMATTED_SIZE_DECIMAL false ;
55 u64 U64_FORMATTED_SIZE U64_FORMATTED_SIZE_DECIMAL false ;
56 u128 U128_FORMATTED_SIZE U128_FORMATTED_SIZE_DECIMAL false ;
57 usize USIZE_FORMATTED_SIZE USIZE_FORMATTED_SIZE_DECIMAL false ;
58 i8 I8_FORMATTED_SIZE I8_FORMATTED_SIZE_DECIMAL true ;
59 i16 I16_FORMATTED_SIZE I16_FORMATTED_SIZE_DECIMAL true ;
60 i32 I32_FORMATTED_SIZE I32_FORMATTED_SIZE_DECIMAL true ;
61 i64 I64_FORMATTED_SIZE I64_FORMATTED_SIZE_DECIMAL true ;
62 i128 I128_FORMATTED_SIZE I128_FORMATTED_SIZE_DECIMAL true ;
63 isize ISIZE_FORMATTED_SIZE ISIZE_FORMATTED_SIZE_DECIMAL true ;
64 f32 F32_FORMATTED_SIZE F32_FORMATTED_SIZE_DECIMAL true ;
65 f64 F64_FORMATTED_SIZE F64_FORMATTED_SIZE_DECIMAL true ;
66 }
67
68 // INTEGER
69
70 /// Defines a trait that supports integral operations.
71 #[doc(hidden)]
72 pub trait Integer:
73 // Basic
74 Number + Eq + Ord +
75 // Display
76 fmt::Octal + fmt::LowerHex + fmt::UpperHex +
77 //Operations
78 ops::BitAnd<Output=Self> +
79 ops::BitAndAssign +
80 ops::BitOr<Output=Self> +
81 ops::BitOrAssign +
82 ops::BitXor<Output=Self> +
83 ops::BitXorAssign +
84 ops::Not +
85 ops::Shl<Self, Output=Self> +
86 ops::Shl<u8, Output=Self> +
87 ops::Shl<u16, Output=Self> +
88 ops::Shl<u32, Output=Self> +
89 ops::Shl<u64, Output=Self> +
90 ops::Shl<usize, Output=Self> +
91 ops::Shl<i8, Output=Self> +
92 ops::Shl<i16, Output=Self> +
93 ops::Shl<i64, Output=Self> +
94 ops::Shl<isize, Output=Self> +
95 ops::Shl<i32, Output=Self> +
96 ops::ShlAssign<Self> +
97 ops::ShlAssign<u8> +
98 ops::ShlAssign<u16> +
99 ops::ShlAssign<u32> +
100 ops::ShlAssign<u64> +
101 ops::ShlAssign<usize> +
102 ops::ShlAssign<i8> +
103 ops::ShlAssign<i16> +
104 ops::ShlAssign<i32> +
105 ops::ShlAssign<i64> +
106 ops::ShlAssign<isize> +
107 ops::Shr<Self, Output=Self> +
108 ops::Shr<u8, Output=Self> +
109 ops::Shr<u16, Output=Self> +
110 ops::Shr<u32, Output=Self> +
111 ops::Shr<u64, Output=Self> +
112 ops::Shr<usize, Output=Self> +
113 ops::Shr<i8, Output=Self> +
114 ops::Shr<i16, Output=Self> +
115 ops::Shr<i64, Output=Self> +
116 ops::Shr<isize, Output=Self> +
117 ops::Shr<i32, Output=Self> +
118 ops::ShrAssign<Self> +
119 ops::ShrAssign<u8> +
120 ops::ShrAssign<u16> +
121 ops::ShrAssign<u32> +
122 ops::ShrAssign<u64> +
123 ops::ShrAssign<usize> +
124 ops::ShrAssign<i8> +
125 ops::ShrAssign<i16> +
126 ops::ShrAssign<i32> +
127 ops::ShrAssign<i64> +
128 ops::ShrAssign<isize>
129 {
130 // CONSTANTS
131 const ZERO: Self;
132 const ONE: Self;
133 const TWO: Self;
134 const MAX: Self;
135 const MIN: Self;
136 const BITS: usize;
137
138 // FUNCTIONS (INHERITED)
max_value() -> Self139 fn max_value() -> Self;
min_value() -> Self140 fn min_value() -> Self;
count_ones(self) -> u32141 fn count_ones(self) -> u32;
count_zeros(self) -> u32142 fn count_zeros(self) -> u32;
leading_zeros(self) -> u32143 fn leading_zeros(self) -> u32;
trailing_zeros(self) -> u32144 fn trailing_zeros(self) -> u32;
pow(self, i: u32) -> Self145 fn pow(self, i: u32) -> Self;
checked_add(self, i: Self) -> Option<Self>146 fn checked_add(self, i: Self) -> Option<Self>;
checked_sub(self, i: Self) -> Option<Self>147 fn checked_sub(self, i: Self) -> Option<Self>;
checked_mul(self, i: Self) -> Option<Self>148 fn checked_mul(self, i: Self) -> Option<Self>;
checked_div(self, i: Self) -> Option<Self>149 fn checked_div(self, i: Self) -> Option<Self>;
checked_rem(self, i: Self) -> Option<Self>150 fn checked_rem(self, i: Self) -> Option<Self>;
checked_neg(self) -> Option<Self>151 fn checked_neg(self) -> Option<Self>;
checked_shl(self, i: u32) -> Option<Self>152 fn checked_shl(self, i: u32) -> Option<Self>;
checked_shr(self, i: u32) -> Option<Self>153 fn checked_shr(self, i: u32) -> Option<Self>;
wrapping_add(self, i: Self) -> Self154 fn wrapping_add(self, i: Self) -> Self;
wrapping_sub(self, i: Self) -> Self155 fn wrapping_sub(self, i: Self) -> Self;
wrapping_mul(self, i: Self) -> Self156 fn wrapping_mul(self, i: Self) -> Self;
wrapping_div(self, i: Self) -> Self157 fn wrapping_div(self, i: Self) -> Self;
wrapping_rem(self, i: Self) -> Self158 fn wrapping_rem(self, i: Self) -> Self;
wrapping_neg(self) -> Self159 fn wrapping_neg(self) -> Self;
wrapping_shl(self, i: u32) -> Self160 fn wrapping_shl(self, i: u32) -> Self;
wrapping_shr(self, i: u32) -> Self161 fn wrapping_shr(self, i: u32) -> Self;
overflowing_add(self, i: Self) -> (Self, bool)162 fn overflowing_add(self, i: Self) -> (Self, bool);
overflowing_sub(self, i: Self) -> (Self, bool)163 fn overflowing_sub(self, i: Self) -> (Self, bool);
overflowing_mul(self, i: Self) -> (Self, bool)164 fn overflowing_mul(self, i: Self) -> (Self, bool);
overflowing_div(self, i: Self) -> (Self, bool)165 fn overflowing_div(self, i: Self) -> (Self, bool);
overflowing_rem(self, i: Self) -> (Self, bool)166 fn overflowing_rem(self, i: Self) -> (Self, bool);
overflowing_neg(self) -> (Self, bool)167 fn overflowing_neg(self) -> (Self, bool);
overflowing_shl(self, i: u32) -> (Self, bool)168 fn overflowing_shl(self, i: u32) -> (Self, bool);
overflowing_shr(self, i: u32) -> (Self, bool)169 fn overflowing_shr(self, i: u32) -> (Self, bool);
saturating_add(self, i: Self) -> Self170 fn saturating_add(self, i: Self) -> Self;
saturating_sub(self, i: Self) -> Self171 fn saturating_sub(self, i: Self) -> Self;
saturating_mul(self, i: Self) -> Self172 fn saturating_mul(self, i: Self) -> Self;
173
174 /// Create literal zero.
175 #[inline]
zero() -> Self176 fn zero() -> Self {
177 Self::ZERO
178 }
179
180 /// Create literal one.
181 #[inline]
one() -> Self182 fn one() -> Self {
183 Self::ONE
184 }
185
186 /// Create literal two.
187 #[inline]
two() -> Self188 fn two() -> Self {
189 Self::TWO
190 }
191
192 /// Check if value is equal to zero.
193 #[inline]
is_zero(self) -> bool194 fn is_zero(self) -> bool {
195 self == Self::ZERO
196 }
197
198 /// Check if value is equal to one.
199 #[inline]
is_one(self) -> bool200 fn is_one(self) -> bool {
201 self == Self::ONE
202 }
203
204 // OPERATIONS
205
206 /// Get the fast ceiling of the quotient from integer division.
207 /// Not safe, since the remainder can easily overflow.
208 #[inline]
ceil_divmod(self, y: Self) -> (Self, i32)209 fn ceil_divmod(self, y: Self) -> (Self, i32) {
210 let q = self / y;
211 let r = self % y;
212 match r.is_zero() {
213 true => (q, r.as_i32()),
214 false => (q + Self::ONE, r.as_i32() - y.as_i32())
215 }
216 }
217
218 /// Get the fast ceiling of the quotient from integer division.
219 /// Not safe, since the remainder can easily overflow.
220 #[inline]
ceil_div(self, y: Self) -> Self221 fn ceil_div(self, y: Self) -> Self {
222 self.ceil_divmod(y).0
223 }
224
225 /// Get the fast ceiling modulus from integer division.
226 /// Not safe, since the remainder can easily overflow.
227 #[inline]
ceil_mod(self, y: Self) -> i32228 fn ceil_mod(self, y: Self) -> i32 {
229 self.ceil_divmod(y).1
230 }
231
232 // PROPERTIES
233
234 /// Get the number of bits in a value.
235 #[inline]
bit_length(self) -> u32236 fn bit_length(self) -> u32 {
237 Self::BITS as u32 - self.leading_zeros()
238 }
239
240 // TRY CAST OR MAX
241
242 #[inline]
try_u8_or_max(self) -> u8243 fn try_u8_or_max(self) -> u8 {
244 try_cast_or_max(self)
245 }
246
247 #[inline]
try_u16_or_max(self) -> u16248 fn try_u16_or_max(self) -> u16 {
249 try_cast_or_max(self)
250 }
251
252 #[inline]
try_u32_or_max(self) -> u32253 fn try_u32_or_max(self) -> u32 {
254 try_cast_or_max(self)
255 }
256
257 #[inline]
try_u64_or_max(self) -> u64258 fn try_u64_or_max(self) -> u64 {
259 try_cast_or_max(self)
260 }
261
262 #[inline]
try_u128_or_max(self) -> u128263 fn try_u128_or_max(self) -> u128 {
264 try_cast_or_max(self)
265 }
266
267 #[inline]
try_usize_or_max(self) -> usize268 fn try_usize_or_max(self) -> usize {
269 try_cast_or_max(self)
270 }
271
272 #[inline]
try_i8_or_max(self) -> i8273 fn try_i8_or_max(self) -> i8 {
274 try_cast_or_max(self)
275 }
276
277 #[inline]
try_i16_or_max(self) -> i16278 fn try_i16_or_max(self) -> i16 {
279 try_cast_or_max(self)
280 }
281
282 #[inline]
try_i32_or_max(self) -> i32283 fn try_i32_or_max(self) -> i32 {
284 try_cast_or_max(self)
285 }
286
287 #[inline]
try_i64_or_max(self) -> i64288 fn try_i64_or_max(self) -> i64 {
289 try_cast_or_max(self)
290 }
291
292 #[inline]
try_i128_or_max(self) -> i128293 fn try_i128_or_max(self) -> i128 {
294 try_cast_or_max(self)
295 }
296
297 #[inline]
try_isize_or_max(self) -> isize298 fn try_isize_or_max(self) -> isize {
299 try_cast_or_max(self)
300 }
301
302 // TRY CAST OR MIN
303
304 #[inline]
try_u8_or_min(self) -> u8305 fn try_u8_or_min(self) -> u8 {
306 try_cast_or_min(self)
307 }
308
309 #[inline]
try_u16_or_min(self) -> u16310 fn try_u16_or_min(self) -> u16 {
311 try_cast_or_min(self)
312 }
313
314 #[inline]
try_u32_or_min(self) -> u32315 fn try_u32_or_min(self) -> u32 {
316 try_cast_or_min(self)
317 }
318
319 #[inline]
try_u64_or_min(self) -> u64320 fn try_u64_or_min(self) -> u64 {
321 try_cast_or_min(self)
322 }
323
324 #[inline]
try_u128_or_min(self) -> u128325 fn try_u128_or_min(self) -> u128 {
326 try_cast_or_min(self)
327 }
328
329 #[inline]
try_usize_or_min(self) -> usize330 fn try_usize_or_min(self) -> usize {
331 try_cast_or_min(self)
332 }
333
334 #[inline]
try_i8_or_min(self) -> i8335 fn try_i8_or_min(self) -> i8 {
336 try_cast_or_min(self)
337 }
338
339 #[inline]
try_i16_or_min(self) -> i16340 fn try_i16_or_min(self) -> i16 {
341 try_cast_or_min(self)
342 }
343
344 #[inline]
try_i32_or_min(self) -> i32345 fn try_i32_or_min(self) -> i32 {
346 try_cast_or_min(self)
347 }
348
349 #[inline]
try_i64_or_min(self) -> i64350 fn try_i64_or_min(self) -> i64 {
351 try_cast_or_min(self)
352 }
353
354 #[inline]
try_i128_or_min(self) -> i128355 fn try_i128_or_min(self) -> i128 {
356 try_cast_or_min(self)
357 }
358
359 #[inline]
try_isize_or_min(self) -> isize360 fn try_isize_or_min(self) -> isize {
361 try_cast_or_min(self)
362 }
363 }
364
365 macro_rules! integer_impl {
366 ($($t:tt)*) => ($(
367 impl Integer for $t {
368 const ZERO: $t = 0;
369 const ONE: $t = 1;
370 const TWO: $t = 2;
371 const MAX: $t = $t::max_value();
372 const MIN: $t = $t::min_value();
373 const BITS: usize = mem::size_of::<$t>() * 8;
374
375 #[inline]
376 fn max_value() -> Self {
377 Self::MAX
378 }
379
380 #[inline]
381 fn min_value() -> Self {
382 Self::MIN
383 }
384
385 #[inline]
386 fn count_ones(self) -> u32 {
387 $t::count_ones(self)
388 }
389
390 #[inline]
391 fn count_zeros(self) -> u32 {
392 $t::count_zeros(self)
393 }
394
395 #[inline]
396 fn leading_zeros(self) -> u32 {
397 $t::leading_zeros(self)
398 }
399
400 #[inline]
401 fn trailing_zeros(self) -> u32 {
402 $t::trailing_zeros(self)
403 }
404
405 #[inline]
406 fn pow(self, i: u32) -> Self {
407 $t::pow(self, i)
408 }
409
410 #[inline]
411 fn checked_add(self, i: Self) -> Option<Self> {
412 $t::checked_add(self, i)
413 }
414
415 #[inline]
416 fn checked_sub(self, i: Self) -> Option<Self> {
417 $t::checked_sub(self, i)
418 }
419
420 #[inline]
421 fn checked_mul(self, i: Self) -> Option<Self> {
422 $t::checked_mul(self, i)
423 }
424
425 #[inline]
426 fn checked_div(self, i: Self) -> Option<Self> {
427 $t::checked_div(self, i)
428 }
429
430 #[inline]
431 fn checked_rem(self, i: Self) -> Option<Self> {
432 $t::checked_rem(self, i)
433 }
434
435 #[inline]
436 fn checked_neg(self) -> Option<Self> {
437 $t::checked_neg(self)
438 }
439
440 #[inline]
441 fn checked_shl(self, i: u32) -> Option<Self> {
442 $t::checked_shl(self,i)
443 }
444
445 #[inline]
446 fn checked_shr(self, i: u32) -> Option<Self> {
447 $t::checked_shr(self,i)
448 }
449
450 #[inline]
451 fn wrapping_add(self, i: Self) -> Self {
452 $t::wrapping_add(self, i)
453 }
454
455 #[inline]
456 fn wrapping_sub(self, i: Self) -> Self {
457 $t::wrapping_sub(self, i)
458 }
459
460 #[inline]
461 fn wrapping_mul(self, i: Self) -> Self {
462 $t::wrapping_mul(self, i)
463 }
464
465 #[inline]
466 fn wrapping_div(self, i: Self) -> Self {
467 $t::wrapping_div(self, i)
468 }
469
470 #[inline]
471 fn wrapping_rem(self, i: Self) -> Self {
472 $t::wrapping_rem(self, i)
473 }
474
475 #[inline]
476 fn wrapping_neg(self) -> Self {
477 $t::wrapping_neg(self)
478 }
479
480 #[inline]
481 fn wrapping_shl(self, i: u32) -> Self {
482 $t::wrapping_shl(self,i)
483 }
484
485 #[inline]
486 fn wrapping_shr(self, i: u32) -> Self {
487 $t::wrapping_shr(self,i)
488 }
489
490 #[inline]
491 fn overflowing_add(self, i: Self) -> (Self, bool) {
492 $t::overflowing_add(self, i)
493 }
494
495 #[inline]
496 fn overflowing_sub(self, i: Self) -> (Self, bool) {
497 $t::overflowing_sub(self, i)
498 }
499
500 #[inline]
501 fn overflowing_mul(self, i: Self) -> (Self, bool) {
502 $t::overflowing_mul(self, i)
503 }
504
505 #[inline]
506 fn overflowing_div(self, i: Self) -> (Self, bool) {
507 $t::overflowing_div(self, i)
508 }
509
510 #[inline]
511 fn overflowing_rem(self, i: Self) -> (Self, bool) {
512 $t::overflowing_rem(self, i)
513 }
514
515 #[inline]
516 fn overflowing_neg(self) -> (Self, bool) {
517 $t::overflowing_neg(self)
518 }
519
520 #[inline]
521 fn overflowing_shl(self, i: u32) -> (Self, bool) {
522 $t::overflowing_shl(self,i)
523 }
524
525 #[inline]
526 fn overflowing_shr(self, i: u32) -> (Self, bool) {
527 $t::overflowing_shr(self,i)
528 }
529
530 #[inline]
531 fn saturating_add(self, i: Self) -> Self {
532 $t::saturating_add(self, i)
533 }
534
535 #[inline]
536 fn saturating_sub(self, i: Self) -> Self {
537 $t::saturating_sub(self, i)
538 }
539
540 #[inline]
541 fn saturating_mul(self, i: Self) -> Self {
542 $t::saturating_mul(self, i)
543 }
544 }
545 )*)
546 }
547
548 integer_impl! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize }
549
550 /// Unwrap or get T::max_value().
551 #[inline]
unwrap_or_max<T: Integer>(t: Option<T>) -> T552 pub(crate) fn unwrap_or_max<T: Integer>(t: Option<T>) -> T {
553 t.unwrap_or(T::max_value())
554 }
555
556 /// Unwrap or get T::min_value().
557 #[inline]
unwrap_or_min<T: Integer>(t: Option<T>) -> T558 pub(crate) fn unwrap_or_min<T: Integer>(t: Option<T>) -> T {
559 t.unwrap_or(T::min_value())
560 }
561
562 /// Try to convert to U, if not, return U::max_value().
563 #[inline]
try_cast_or_max<U: Integer, T: TryCast<U>>(t: T) -> U564 pub(crate) fn try_cast_or_max<U: Integer, T: TryCast<U>>(t: T) -> U {
565 unwrap_or_max(TryCast::try_cast(t))
566 }
567
568 /// Try to convert to U, if not, return U::min_value().
569 #[inline]
try_cast_or_min<U: Integer, T: TryCast<U>>(t: T) -> U570 pub(crate) fn try_cast_or_min<U: Integer, T: TryCast<U>>(t: T) -> U {
571 unwrap_or_min(TryCast::try_cast(t))
572 }
573
574 // SIGNED INTEGER
575
576 /// Defines a trait that supports signed integral operations.
577 #[doc(hidden)]
578 pub trait SignedInteger: Integer + ops::Neg<Output=Self>
579 {
580 // FUNCTIONS (INHERITED)
checked_abs(self) -> Option<Self>581 fn checked_abs(self) -> Option<Self>;
wrapping_abs(self) -> Self582 fn wrapping_abs(self) -> Self;
overflowing_abs(self) -> (Self, bool)583 fn overflowing_abs(self) -> (Self, bool);
584 }
585
586 macro_rules! signed_integer_impl {
587 ($($t:tt)*) => ($(
588 impl SignedInteger for $t {
589 fn checked_abs(self) -> Option<Self> {
590 $t::checked_abs(self)
591 }
592
593 fn wrapping_abs(self) -> Self {
594 $t::wrapping_abs(self)
595 }
596
597 fn overflowing_abs(self) -> (Self, bool) {
598 $t::overflowing_abs(self)
599 }
600 }
601 )*)
602 }
603
604 signed_integer_impl! { i8 i16 i32 i64 i128 isize }
605
606 // UNSIGNED INTEGER
607
608 /// Defines a trait that supports unsigned integral operations.
609 #[doc(hidden)]
610 pub trait UnsignedInteger: Integer
611 {
612 /// Returns true if the least-significant bit is odd.
613 #[inline]
is_odd(self) -> bool614 fn is_odd(self) -> bool {
615 self & Self::ONE == Self::ONE
616 }
617
618 /// Returns true if the least-significant bit is even.
619 #[inline]
is_even(self) -> bool620 fn is_even(self) -> bool {
621 !self.is_odd()
622 }
623 }
624
625 macro_rules! unsigned_integer_impl {
626 ($($t:ty)*) => ($(
627 impl UnsignedInteger for $t {}
628 )*)
629 }
630
631 unsigned_integer_impl! { u8 u16 u32 u64 u128 usize }
632
633 // FLOAT
634
635 /// Float information for native float types.
636 #[doc(hidden)]
637 pub trait Float: Number + ops::Neg<Output=Self>
638 {
639 /// Unsigned type of the same size.
640 type Unsigned: UnsignedInteger;
641
642 // CONSTANTS
643 const ZERO: Self;
644 const ONE: Self;
645 const TWO: Self;
646 const MAX: Self;
647 const MIN: Self;
648 const INFINITY: Self;
649 const NEG_INFINITY: Self;
650 const NAN: Self;
651 const BITS: usize;
652
653 /// Bitmask for the sign bit.
654 const SIGN_MASK: Self::Unsigned;
655 /// Bitmask for the exponent, including the hidden bit.
656 const EXPONENT_MASK: Self::Unsigned;
657 /// Bitmask for the hidden bit in exponent, which is an implicit 1 in the fraction.
658 const HIDDEN_BIT_MASK: Self::Unsigned;
659 /// Bitmask for the mantissa (fraction), excluding the hidden bit.
660 const MANTISSA_MASK: Self::Unsigned;
661
662 // PROPERTIES
663
664 /// Positive infinity as bits.
665 const INFINITY_BITS: Self::Unsigned;
666 /// Positive infinity as bits.
667 const NEGATIVE_INFINITY_BITS: Self::Unsigned;
668 /// Size of the significand (mantissa) without hidden bit.
669 const MANTISSA_SIZE: i32;
670 /// Bias of the exponet
671 const EXPONENT_BIAS: i32;
672 /// Exponent portion of a denormal float.
673 const DENORMAL_EXPONENT: i32;
674 /// Maximum exponent value in float.
675 const MAX_EXPONENT: i32;
676
677 // FUNCTIONS (INHERITED)
678
679 // Re-export the to and from bits methods.
abs(self) -> Self680 fn abs(self) -> Self;
ceil(self) -> Self681 fn ceil(self) -> Self;
exp(self) -> Self682 fn exp(self) -> Self;
floor(self) -> Self683 fn floor(self) -> Self;
ln(self) -> Self684 fn ln(self) -> Self;
powi(self, n: i32) -> Self685 fn powi(self, n: i32) -> Self;
powf(self, f: Self) -> Self686 fn powf(self, f: Self) -> Self;
round(self) -> Self687 fn round(self) -> Self;
to_bits(self) -> Self::Unsigned688 fn to_bits(self) -> Self::Unsigned;
from_bits(u: Self::Unsigned) -> Self689 fn from_bits(u: Self::Unsigned) -> Self;
is_sign_positive(self) -> bool690 fn is_sign_positive(self) -> bool;
is_sign_negative(self) -> bool691 fn is_sign_negative(self) -> bool;
692
693 // FUNCTIONS
694
695 /// Check if value is equal to zero.
696 #[inline]
is_zero(self) -> bool697 fn is_zero(self) -> bool {
698 // IEEE754 guarantees `+0.0 == -0.0`, and Rust respects this,
699 // unlike some other languages.
700 self == Self::ZERO
701 }
702
703 /// Check if value is equal to one.
704 #[inline]
is_one(self) -> bool705 fn is_one(self) -> bool {
706 self == Self::ONE
707 }
708
709 /// Returns true if the float is a denormal.
710 #[inline]
is_denormal(self) -> bool711 fn is_denormal(self) -> bool {
712 self.to_bits() & Self::EXPONENT_MASK == Self::Unsigned::ZERO
713 }
714
715 /// Returns true if the float is a NaN or Infinite.
716 #[inline]
is_special(self) -> bool717 fn is_special(self) -> bool {
718 self.to_bits() & Self::EXPONENT_MASK == Self::EXPONENT_MASK
719 }
720
721 /// Returns true if the float is NaN.
722 #[inline]
is_nan(self) -> bool723 fn is_nan(self) -> bool {
724 self.is_special() && !(self.to_bits() & Self::MANTISSA_MASK).is_zero()
725 }
726
727 /// Returns true if the float is infinite.
728 #[inline]
is_inf(self) -> bool729 fn is_inf(self) -> bool {
730 self.is_special() && (self.to_bits() & Self::MANTISSA_MASK).is_zero()
731 }
732
733 /// Returns true if the float's least-significant mantissa bit is odd.
734 #[inline]
is_odd(self) -> bool735 fn is_odd(self) -> bool {
736 self.to_bits().is_odd()
737 }
738
739 /// Returns true if the float's least-significant mantissa bit is even.
740 #[inline]
is_even(self) -> bool741 fn is_even(self) -> bool {
742 !self.is_odd()
743 }
744
745 /// Get exponent component from the float.
746 #[inline]
exponent(self) -> i32747 fn exponent(self) -> i32 {
748 if self.is_denormal() {
749 return Self::DENORMAL_EXPONENT;
750 }
751
752 let bits = self.to_bits();
753 let biased_e: i32 = AsCast::as_cast((bits & Self::EXPONENT_MASK) >> Self::MANTISSA_SIZE);
754 biased_e - Self::EXPONENT_BIAS
755 }
756
757 /// Get mantissa (significand) component from float.
758 #[inline]
mantissa(self) -> Self::Unsigned759 fn mantissa(self) -> Self::Unsigned {
760 let bits = self.to_bits();
761 let s = bits & Self::MANTISSA_MASK;
762 if !self.is_denormal() {
763 s + Self::HIDDEN_BIT_MASK
764 } else {
765 s
766 }
767 }
768
769 /// Get next greater float.
770 #[inline]
next(self) -> Self771 fn next(self) -> Self {
772 let bits = self.to_bits();
773 if self.is_sign_negative() && self.is_zero() {
774 // -0.0
775 Self::ZERO
776 } else if bits == Self::INFINITY_BITS {
777 Self::from_bits(Self::INFINITY_BITS)
778 } else if self.is_sign_negative() {
779 Self::from_bits(bits.saturating_sub(Self::Unsigned::ONE))
780 } else {
781 Self::from_bits(bits.saturating_add(Self::Unsigned::ONE))
782 }
783 }
784
785 /// Get next greater float for a positive float.
786 /// Value must be >= 0.0 and < INFINITY.
787 #[inline]
next_positive(self) -> Self788 fn next_positive(self) -> Self {
789 debug_assert!(self.is_sign_positive() && !self.is_inf());
790 Self::from_bits(self.to_bits() + Self::Unsigned::ONE)
791 }
792
793 /// Get previous greater float, such that `self.prev().next() == self`.
794 #[inline]
prev(self) -> Self795 fn prev(self) -> Self {
796 let bits = self.to_bits();
797 if self.is_sign_positive() && self.is_zero() {
798 // +0.0
799 -Self::ZERO
800 } else if bits == Self::NEGATIVE_INFINITY_BITS {
801 Self::from_bits(Self::NEGATIVE_INFINITY_BITS)
802 } else if self.is_sign_negative() {
803 Self::from_bits(bits.saturating_add(Self::Unsigned::ONE))
804 } else {
805 Self::from_bits(bits.saturating_sub(Self::Unsigned::ONE))
806 }
807 }
808
809 /// Get previous greater float for a positive float.
810 /// Value must be > 0.0.
811 #[inline]
prev_positive(self) -> Self812 fn prev_positive(self) -> Self {
813 debug_assert!(self.is_sign_positive() && !self.is_zero());
814 return Self::from_bits(self.to_bits() - Self::Unsigned::ONE);
815 }
816
817 /// Round a positive number to even.
818 #[inline]
round_positive_even(self) -> Self819 fn round_positive_even(self) -> Self {
820 if self.mantissa().is_odd() {
821 self.next_positive()
822 } else {
823 self
824 }
825 }
826
827 /// Get the max of two finite numbers.
828 #[inline]
max_finite(self, f: Self) -> Self829 fn max_finite(self, f: Self) -> Self {
830 debug_assert!(!self.is_special() && !f.is_special(), "max_finite self={} f={}", self, f);
831 if self < f { f } else { self }
832 }
833
834 /// Get the min of two finite numbers.
835 #[inline]
min_finite(self, f: Self) -> Self836 fn min_finite(self, f: Self) -> Self {
837 debug_assert!(!self.is_special() && !f.is_special(), "min_finite self={} f={}", self, f);
838 if self < f { self } else { f }
839 }
840 }
841
842 /// Wrap float method for `std` and `no_std` context.
843 macro_rules! float_method {
844 ($f:ident, $t:tt, $meth:ident, $intr:ident, $libm:ident $(,$i:expr)*) => ({
845 #[cfg(feature = "std")]
846 return $t::$meth($f $(,$i)*);
847
848 #[cfg(all(not(feature = "std"), feature = "libm"))]
849 return libm::$libm($f $(,$i)*);
850
851 #[cfg(all(not(feature = "std"), not(feature = "libm")))]
852 return unsafe { core::intrinsics::$intr($f $(,$i)*) };
853 })
854 }
855
856 /// Wrap float method with special conditions for MSVC.
857 ///
858 /// This is because MSVC wraps these as inline functions, with no actual
859 /// ABI for the LLVM intrinsic.
860 macro_rules! float_method_msvc {
861 ($f:ident, $ts:tt, $tl:tt, $meth:ident, $intr:ident, $libm:ident $(,$i:expr)*) => ({
862 #[cfg(feature = "std")]
863 return $ts::$meth($f $(,$i)*);
864
865 #[cfg(all(not(feature = "std"), feature = "libm"))]
866 return libm::$libm($f $(,$i)*);
867
868 #[cfg(all(not(feature = "std"), not(feature = "libm"), not(target_env = "msvc")))]
869 return unsafe { core::intrinsics::$intr($f $(,$i)*) };
870
871 #[cfg(all(not(feature = "std"), not(feature = "libm"), target_env = "msvc"))]
872 return $tl::$meth($f as $tl $(,$i as $tl)*) as $ts;
873 })
874 }
875
876 /// Wrap float log method for `no_std` context, with special conditions for Solaris.
877 ///
878 /// Solaris has a standard non-conforming log implementation, we need
879 /// to wrap this cheaply.
880 macro_rules! float_method_log_solaris {
881 ($f:ident, $t:tt, $meth:ident, $intr:ident, $libm:ident $(,$i:expr)*) => ({
882 #[cfg(feature = "std")]
883 return $t::$meth($f $(,$i)*);
884
885 #[cfg(all(not(feature = "std"), feature = "libm"))]
886 return libm::$libm($f $(,$i)*);
887
888 #[cfg(all(not(feature = "std"), not(feature = "libm"), not(target_os = "solaris")))]
889 return unsafe { core::intrinsics::$intr($f $(,$i)*) };
890
891 // Workaround for Solaris/Illumos due to log(-value) == -Inf, not NaN.
892 #[cfg(all(not(feature = "std"), not(feature = "libm"), target_os = "solaris"))] {
893 if $f.is_nan() {
894 $f
895 } else if $f.is_special() {
896 if $f > $t::ZERO { $f } else { $t::NAN }
897 } else if $f > $t::ZERO {
898 unsafe { core::intrinsics::$intr($f $(,$i)*) }
899 } else if $f.is_zero() {
900 $t::NEG_INFINITY
901 } else {
902 $t::NAN
903 }
904 }
905 })
906 }
907
908 impl Float for f32 {
909 type Unsigned = u32;
910 const ZERO: f32 = 0.0;
911 const ONE: f32 = 1.0;
912 const TWO: f32 = 2.0;
913 const MAX: f32 = f32::MAX;
914 const MIN: f32 = f32::MIN;
915 const INFINITY: f32 = f32::INFINITY;
916 const NEG_INFINITY: f32 = f32::NEG_INFINITY;
917 const NAN: f32 = f32::NAN;
918 const BITS: usize = 32;
919 const SIGN_MASK: u32 = 0x80000000;
920 const EXPONENT_MASK: u32 = 0x7F800000;
921 const HIDDEN_BIT_MASK: u32 = 0x00800000;
922 const MANTISSA_MASK: u32 = 0x007FFFFF;
923 const INFINITY_BITS: u32 = 0x7F800000;
924 const NEGATIVE_INFINITY_BITS: u32 = Self::INFINITY_BITS | Self::SIGN_MASK;
925 const MANTISSA_SIZE: i32 = 23;
926 const EXPONENT_BIAS: i32 = 127 + Self::MANTISSA_SIZE;
927 const DENORMAL_EXPONENT: i32 = 1 - Self::EXPONENT_BIAS;
928 const MAX_EXPONENT: i32 = 0xFF - Self::EXPONENT_BIAS;
929
930 #[inline]
abs(self) -> f32931 fn abs(self) -> f32 {
932 float_method!(self, f32, abs, fabsf32, fabsf)
933 }
934
935 #[inline]
ceil(self) -> f32936 fn ceil(self) -> f32 {
937 float_method_msvc!(self, f32, f64, ceil, ceilf32, ceilf)
938 }
939
940 #[inline]
exp(self) -> f32941 fn exp(self) -> f32 {
942 float_method_msvc!(self, f32, f64, exp, expf32, expf)
943 }
944
945 #[inline]
floor(self) -> f32946 fn floor(self) -> f32 {
947 float_method_msvc!(self, f32, f64, floor, floorf32, floorf)
948 }
949
950 #[inline]
ln(self) -> f32951 fn ln(self) -> f32 {
952 float_method_msvc!(self, f32, f64, ln, logf32, logf)
953 }
954
955 #[inline]
powi(self, n: i32) -> f32956 fn powi(self, n: i32) -> f32 {
957 cfg_if! {
958 if #[cfg(all(not(feature = "std"), feature = "libm"))] {
959 self.powf(n as f32)
960 } else {
961 float_method!(self, f32, powi, powif32, powif, n)
962 }
963 }
964 }
965
966 #[inline]
powf(self, n: f32) -> f32967 fn powf(self, n: f32) -> f32 {
968 float_method_msvc!(self, f32, f64, powf, powf32, powf, n)
969 }
970
971 #[inline]
round(self) -> f32972 fn round(self) -> f32 {
973 float_method!(self, f32, round, roundf32, roundf)
974 }
975
976 #[inline]
to_bits(self) -> u32977 fn to_bits(self) -> u32 {
978 f32::to_bits(self)
979 }
980
981 #[inline]
from_bits(u: u32) -> f32982 fn from_bits(u: u32) -> f32 {
983 f32::from_bits(u)
984 }
985
986 #[inline]
is_sign_positive(self) -> bool987 fn is_sign_positive(self) -> bool {
988 f32::is_sign_positive(self)
989 }
990
991 #[inline]
is_sign_negative(self) -> bool992 fn is_sign_negative(self) -> bool {
993 f32::is_sign_negative(self)
994 }
995 }
996
997 impl Float for f64 {
998 type Unsigned = u64;
999 const ZERO: f64 = 0.0;
1000 const ONE: f64 = 1.0;
1001 const TWO: f64 = 2.0;
1002 const MAX: f64 = f64::MAX;
1003 const MIN: f64 = f64::MIN;
1004 const INFINITY: f64 = f64::INFINITY;
1005 const NEG_INFINITY: f64 = f64::NEG_INFINITY;
1006 const NAN: f64 = f64::NAN;
1007 const BITS: usize = 64;
1008 const SIGN_MASK: u64 = 0x8000000000000000;
1009 const EXPONENT_MASK: u64 = 0x7FF0000000000000;
1010 const HIDDEN_BIT_MASK: u64 = 0x0010000000000000;
1011 const MANTISSA_MASK: u64 = 0x000FFFFFFFFFFFFF;
1012 const INFINITY_BITS: u64 = 0x7FF0000000000000;
1013 const NEGATIVE_INFINITY_BITS: u64 = Self::INFINITY_BITS | Self::SIGN_MASK;
1014 const MANTISSA_SIZE: i32 = 52;
1015 const EXPONENT_BIAS: i32 = 1023 + Self::MANTISSA_SIZE;
1016 const DENORMAL_EXPONENT: i32 = 1 - Self::EXPONENT_BIAS;
1017 const MAX_EXPONENT: i32 = 0x7FF - Self::EXPONENT_BIAS;
1018
1019 #[inline]
abs(self) -> f641020 fn abs(self) -> f64 {
1021 float_method!(self, f64, abs, fabsf64, fabs)
1022 }
1023
1024 #[inline]
ceil(self) -> f641025 fn ceil(self) -> f64 {
1026 float_method!(self, f64, ceil, ceilf64, ceil)
1027 }
1028
1029 #[inline]
exp(self) -> f641030 fn exp(self) -> f64 {
1031 float_method!(self, f64, exp, expf64, exp)
1032 }
1033
1034 #[inline]
floor(self) -> f641035 fn floor(self) -> f64 {
1036 float_method!(self, f64, floor, floorf64, floor)
1037 }
1038
1039 #[inline]
ln(self) -> f641040 fn ln(self) -> f64 {
1041 float_method_log_solaris!(self, f64, ln, logf64, log)
1042 }
1043
1044 #[inline]
powi(self, n: i32) -> f641045 fn powi(self, n: i32) -> f64 {
1046 cfg_if! {
1047 if #[cfg(all(not(feature = "std"), feature = "libm"))] {
1048 self.powf(n as f64)
1049 } else {
1050 float_method!(self, f64, powi, powif64, powi, n)
1051 }
1052 }
1053 }
1054
1055 #[inline]
powf(self, n: f64) -> f641056 fn powf(self, n: f64) -> f64 {
1057 float_method!(self, f64, powf, powf64, pow, n)
1058 }
1059
1060 #[inline]
round(self) -> f641061 fn round(self) -> f64 {
1062 float_method!(self, f64, round, roundf64, round)
1063 }
1064
1065 #[inline]
to_bits(self) -> u641066 fn to_bits(self) -> u64 {
1067 f64::to_bits(self)
1068 }
1069
1070 #[inline]
from_bits(u: u64) -> f641071 fn from_bits(u: u64) -> f64 {
1072 f64::from_bits(u)
1073 }
1074
1075 #[inline]
is_sign_positive(self) -> bool1076 fn is_sign_positive(self) -> bool {
1077 f64::is_sign_positive(self)
1078 }
1079
1080 #[inline]
is_sign_negative(self) -> bool1081 fn is_sign_negative(self) -> bool {
1082 f64::is_sign_negative(self)
1083 }
1084 }
1085
1086 // TEST
1087 // ----
1088
1089 #[cfg(test)]
1090 mod tests {
1091 use super::*;
1092
check_number<T: Number>(x: T, mut y: T)1093 fn check_number<T: Number>(x: T, mut y: T) {
1094 // Copy, partialeq, partialord
1095 let _ = x;
1096 assert!(x < y);
1097 assert!(x != y);
1098
1099 // Operations
1100 let _ = y + x;
1101 let _ = y - x;
1102 let _ = y * x;
1103 let _ = y / x;
1104 let _ = y % x;
1105 y += x;
1106 y -= x;
1107 y *= x;
1108 y /= x;
1109 y %= x;
1110
1111 // Conversions already tested.
1112 }
1113
1114 #[test]
number_test()1115 fn number_test() {
1116 check_number(1u8, 5);
1117 check_number(1u16, 5);
1118 check_number(1u32, 5);
1119 check_number(1u64, 5);
1120 check_number(1u128, 5);
1121 check_number(1usize, 5);
1122 check_number(1i8, 5);
1123 check_number(1i16, 5);
1124 check_number(1i32, 5);
1125 check_number(1i64, 5);
1126 check_number(1i128, 5);
1127 check_number(1isize, 5);
1128 check_number(1f32, 5.0);
1129 check_number(1f64, 5.0);
1130 }
1131
check_integer<T: Integer>(mut x: T)1132 fn check_integer<T: Integer>(mut x: T) {
1133 // Copy, partialeq, partialord, ord, eq
1134 let _ = x;
1135 assert!(x > T::ONE);
1136 assert!(x != T::ONE);
1137 assert_eq!(x.min(T::ONE), T::ONE);
1138 assert_eq!(x.max(T::ONE), x);
1139
1140 // Operations
1141 let _ = x + T::ONE;
1142 let _ = x - T::ONE;
1143 let _ = x * T::ONE;
1144 let _ = x / T::ONE;
1145 let _ = x % T::ONE;
1146 x += T::ONE;
1147 x -= T::ONE;
1148 x *= T::ONE;
1149 x /= T::ONE;
1150 x %= T::ONE;
1151
1152 // Bitwise operations
1153 let _ = x & T::ONE;
1154 let _ = x | T::ONE;
1155 let _ = x ^ T::ONE;
1156 let _ = !x;
1157 x &= T::ONE;
1158 x |= T::ONE;
1159 x ^= T::ONE;
1160
1161 // Bitshifts
1162 let _ = x << 1u8;
1163 let _ = x << 1u16;
1164 let _ = x << 1u32;
1165 let _ = x << 1u64;
1166 let _ = x << 1usize;
1167 let _ = x << 1i8;
1168 let _ = x << 1i16;
1169 let _ = x << 1i32;
1170 let _ = x << 1i64;
1171 let _ = x << 1isize;
1172 let _ = x >> 1u8;
1173 let _ = x >> 1u16;
1174 let _ = x >> 1u32;
1175 let _ = x >> 1u64;
1176 let _ = x >> 1usize;
1177 let _ = x >> 1i8;
1178 let _ = x >> 1i16;
1179 let _ = x >> 1i32;
1180 let _ = x >> 1i64;
1181 let _ = x >> 1isize;
1182 x <<= 1u8;
1183 x <<= 1u16;
1184 x <<= 1u32;
1185 x <<= 1u64;
1186 x <<= 1usize;
1187 x <<= 1i8;
1188 x <<= 1i16;
1189 x <<= 1i32;
1190 x <<= 1i64;
1191 x <<= 1isize;
1192 x >>= 1u8;
1193 x >>= 1u16;
1194 x >>= 1u32;
1195 x >>= 1u64;
1196 x >>= 1usize;
1197 x >>= 1i8;
1198 x >>= 1i16;
1199 x >>= 1i32;
1200 x >>= 1i64;
1201 x >>= 1isize;
1202
1203 // Functions
1204 assert!(T::ZERO.is_zero());
1205 assert!(!T::ONE.is_zero());
1206 assert!(T::ONE.is_one());
1207 assert!(!T::ZERO.is_one());
1208
1209 // Conversions already tested.
1210 }
1211
1212 #[test]
integer_test()1213 fn integer_test() {
1214 check_integer(65u8);
1215 check_integer(65u16);
1216 check_integer(65u32);
1217 check_integer(65u64);
1218 check_integer(65u128);
1219 check_integer(65usize);
1220 check_integer(65i8);
1221 check_integer(65i16);
1222 check_integer(65i32);
1223 check_integer(65i64);
1224 check_integer(65i128);
1225 check_integer(65isize);
1226 }
1227
1228 #[test]
ceil_divmod_test()1229 fn ceil_divmod_test() {
1230 assert_eq!(5usize.ceil_divmod(7), (1, -2));
1231 assert_eq!(0usize.ceil_divmod(7), (0, 0));
1232 assert_eq!(35usize.ceil_divmod(7), (5, 0));
1233 assert_eq!(36usize.ceil_divmod(7), (6, -6));
1234 }
1235
1236 #[test]
unwrap_or_max_test()1237 fn unwrap_or_max_test() {
1238 let x: Option<u8> = None;
1239 assert_eq!(unwrap_or_max(x), u8::max_value());
1240
1241 let x: Option<u8> = Some(1);
1242 assert_eq!(unwrap_or_max(x), 1);
1243 }
1244
1245 #[test]
unwrap_or_min_test()1246 fn unwrap_or_min_test() {
1247 let x: Option<u8> = None;
1248 assert_eq!(unwrap_or_min(x), u8::min_value());
1249
1250 let x: Option<u8> = Some(1);
1251 assert_eq!(unwrap_or_min(x), 1);
1252 }
1253
1254 #[test]
try_cast_or_max_test()1255 fn try_cast_or_max_test() {
1256 let x: u8 = try_cast_or_max(u16::min_value());
1257 assert_eq!(x, u8::min_value());
1258
1259 let x: u8 = try_cast_or_max(u8::max_value() as u16);
1260 assert_eq!(x, u8::max_value());
1261
1262 let x: u8 = try_cast_or_max(u16::max_value());
1263 assert_eq!(x, u8::max_value());
1264 }
1265
1266 #[test]
try_cast_or_min_test()1267 fn try_cast_or_min_test() {
1268 let x: u8 = try_cast_or_min(u16::min_value());
1269 assert_eq!(x, u8::min_value());
1270
1271 let x: u8 = try_cast_or_min(u8::max_value() as u16);
1272 assert_eq!(x, u8::max_value());
1273
1274 let x: u8 = try_cast_or_min(u16::max_value());
1275 assert_eq!(x, u8::min_value());
1276 }
1277
check_float<T: Float>(mut x: T)1278 fn check_float<T: Float>(mut x: T) {
1279 // Copy, partialeq, partialord
1280 let _ = x;
1281 assert!(x > T::ONE);
1282 assert!(x != T::ONE);
1283
1284 // Operations
1285 let _ = x + T::ONE;
1286 let _ = x - T::ONE;
1287 let _ = x * T::ONE;
1288 let _ = x / T::ONE;
1289 let _ = x % T::ONE;
1290 let _ = -x;
1291 x += T::ONE;
1292 x -= T::ONE;
1293 x *= T::ONE;
1294 x /= T::ONE;
1295 x %= T::ONE;
1296
1297 // Check functions
1298 let _ = x.abs();
1299 let _ = x.ceil();
1300 let _ = x.exp();
1301 let _ = x.floor();
1302 let _ = x.ln();
1303 let _ = x.powi(5);
1304 let _ = x.powf(T::ONE);
1305 let _ = x.round();
1306 let _ = x.to_bits();
1307 assert_eq!(T::from_bits(x.to_bits()), x);
1308 let _ = x.is_sign_positive();
1309 let _ = x.is_sign_negative();
1310
1311 // Check properties
1312 let _ = x.to_bits() & T::SIGN_MASK;
1313 let _ = x.to_bits() & T::EXPONENT_MASK;
1314 let _ = x.to_bits() & T::HIDDEN_BIT_MASK;
1315 let _ = x.to_bits() & T::MANTISSA_MASK;
1316 assert!(T::from_bits(T::INFINITY_BITS).is_special());
1317 }
1318
1319 #[test]
float_test()1320 fn float_test() {
1321 check_float(123f32);
1322 check_float(123f64);
1323
1324 // b00000000000000000000000000000001
1325 let f: f32 = 1e-45;
1326 assert!(f.is_odd());
1327 assert!(f.next().is_even());
1328 assert!(f.next_positive().is_even());
1329 assert!(f.prev().is_even());
1330 assert!(f.prev_positive().is_even());
1331 assert!(f.round_positive_even().is_even());
1332 assert_eq!(f.prev().next(), f);
1333 assert_eq!(f.prev_positive().next_positive(), f);
1334 assert_eq!(f.round_positive_even(), f.next());
1335
1336 // b00111101110011001100110011001101
1337 let f: f32 = 0.1;
1338 assert!(f.is_odd());
1339 assert!(f.next().is_even());
1340 assert!(f.next_positive().is_even());
1341 assert!(f.prev().is_even());
1342 assert!(f.prev_positive().is_even());
1343 assert!(f.round_positive_even().is_even());
1344 assert_eq!(f.prev().next(), f);
1345 assert_eq!(f.prev_positive().next_positive(), f);
1346 assert_eq!(f.round_positive_even(), f.next());
1347
1348 // b01000000000000000000000000000000
1349 let f: f32 = 1.0;
1350 assert!(f.is_even());
1351 assert!(f.next().is_odd());
1352 assert!(f.next_positive().is_odd());
1353 assert!(f.prev().is_odd());
1354 assert!(f.prev_positive().is_odd());
1355 assert!(f.round_positive_even().is_even());
1356 assert_eq!(f.prev().next(), f);
1357 assert_eq!(f.prev_positive().next_positive(), f);
1358 assert_ne!(f.round_positive_even(), f.next());
1359 }
1360 }
1361