lexical_util/
num.rs

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#![cfg_attr(any(), rustfmt::skip)]
8
9use core::{fmt, mem, ops};
10
11#[cfg(feature = "f16")]
12use crate::bf16::bf16;
13#[cfg(feature = "f16")]
14use crate::f16::f16;
15
16// AS PRIMITIVE
17// ------------
18
19/// Type that can be converted to primitive with `as`.
20pub trait AsPrimitive: Copy + PartialEq + PartialOrd + Send + Sync + Sized {
21    fn as_u8(self) -> u8;
22    fn as_u16(self) -> u16;
23    fn as_u32(self) -> u32;
24    fn as_u64(self) -> u64;
25    fn as_u128(self) -> u128;
26    fn as_usize(self) -> usize;
27    fn as_i8(self) -> i8;
28    fn as_i16(self) -> i16;
29    fn as_i32(self) -> i32;
30    fn as_i64(self) -> i64;
31    fn as_i128(self) -> i128;
32    fn as_isize(self) -> isize;
33    fn as_f32(self) -> f32;
34    fn as_f64(self) -> f64;
35    fn from_u32(value: u32) -> Self;
36    fn from_u64(value: u64) -> Self;
37
38    #[cfg(feature = "f16")]
39    fn as_f16(self) -> f16;
40
41    #[cfg(feature = "f16")]
42    fn as_bf16(self) -> bf16;
43}
44
45macro_rules! as_primitive {
46    ($($t:ty)*) => ($(
47        impl AsPrimitive for $t {
48            #[inline(always)]
49            fn as_u8(self) -> u8 {
50                self as u8
51            }
52
53            #[inline(always)]
54            fn as_u16(self) -> u16 {
55                self as u16
56            }
57
58            #[inline(always)]
59            fn as_u32(self) -> u32 {
60                self as u32
61            }
62
63            #[inline(always)]
64            fn as_u64(self) -> u64 {
65                self as u64
66            }
67
68            #[inline(always)]
69            fn as_u128(self) -> u128 {
70                self as u128
71            }
72
73            #[inline(always)]
74            fn as_usize(self) -> usize {
75                self as usize
76            }
77
78            #[inline(always)]
79            fn as_i8(self) -> i8 {
80                self as i8
81            }
82
83            #[inline(always)]
84            fn as_i16(self) -> i16 {
85                self as i16
86            }
87
88            #[inline(always)]
89            fn as_i32(self) -> i32 {
90                self as i32
91            }
92
93            #[inline(always)]
94            fn as_i64(self) -> i64 {
95                self as i64
96            }
97
98            #[inline(always)]
99            fn as_i128(self) -> i128 {
100                self as i128
101            }
102
103            #[inline(always)]
104            fn as_isize(self) -> isize {
105                self as isize
106            }
107
108            #[inline(always)]
109            fn as_f32(self) -> f32 {
110                self as f32
111            }
112
113            #[inline(always)]
114            fn as_f64(self) -> f64 {
115                self as f64
116            }
117
118            #[inline(always)]
119            fn from_u32(value: u32) -> Self {
120                value as Self
121            }
122
123            #[inline(always)]
124            fn from_u64(value: u64) -> Self {
125                value as Self
126            }
127
128            #[cfg(feature = "f16")]
129            #[inline(always)]
130            fn as_f16(self) -> f16 {
131                f16::from_f32(self as f32)
132            }
133
134            #[cfg(feature = "f16")]
135            #[inline(always)]
136            fn as_bf16(self) -> bf16 {
137                bf16::from_f32(self as f32)
138            }
139        }
140    )*)
141}
142
143as_primitive! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize f32 f64 }
144
145#[cfg(feature = "f16")]
146macro_rules! half_as_primitive {
147    ($($t:ty)*) => ($(
148        impl AsPrimitive for $t {
149            #[inline(always)]
150            fn as_u8(self) -> u8 {
151                self.as_f32() as u8
152            }
153
154            #[inline(always)]
155            fn as_u16(self) -> u16 {
156                self.as_f32() as u16
157            }
158
159            #[inline(always)]
160            fn as_u32(self) -> u32 {
161                self.as_f32() as u32
162            }
163
164            #[inline(always)]
165            fn as_u64(self) -> u64 {
166                self.as_f32() as u64
167            }
168
169            #[inline(always)]
170            fn as_u128(self) -> u128 {
171                self.as_f32() as u128
172            }
173
174            #[inline(always)]
175            fn as_usize(self) -> usize {
176                self.as_f32() as usize
177            }
178
179            #[inline(always)]
180            fn as_i8(self) -> i8 {
181                self.as_f32() as i8
182            }
183
184            #[inline(always)]
185            fn as_i16(self) -> i16 {
186                self.as_f32() as i16
187            }
188
189            #[inline(always)]
190            fn as_i32(self) -> i32 {
191                self.as_f32() as i32
192            }
193
194            #[inline(always)]
195            fn as_i64(self) -> i64 {
196                self.as_f32() as i64
197            }
198
199            #[inline(always)]
200            fn as_i128(self) -> i128 {
201                self.as_f32() as i128
202            }
203
204            #[inline(always)]
205            fn as_isize(self) -> isize {
206                self.as_f32() as isize
207            }
208
209            #[inline(always)]
210            fn as_f32(self) -> f32 {
211                self.as_f32() as f32
212            }
213
214            #[inline(always)]
215            fn as_f64(self) -> f64 {
216                self.as_f32() as f64
217            }
218
219            #[inline(always)]
220            #[allow(clippy::as_underscore)] // reason="intentionally used in a generic sense"
221            fn from_u32(value: u32) -> Self {
222                Self::from_f32(value as _)
223            }
224
225            #[inline(always)]
226            fn from_u64(value: u64) -> Self {
227                _ = value;
228                unimplemented!()
229            }
230
231            #[inline(always)]
232            fn as_f16(self) -> f16 {
233                f16::from_f32(self.as_f32())
234            }
235
236            #[inline(always)]
237            fn as_bf16(self) -> bf16 {
238                bf16::from_f32(self.as_f32())
239            }
240        }
241    )*)
242}
243
244#[cfg(feature = "f16")]
245half_as_primitive! { f16 bf16 }
246
247// AS CAST
248// -------
249
250/// An interface for casting between machine scalars.
251pub trait AsCast: AsPrimitive {
252    /// Creates a number from another value that can be converted into
253    /// a primitive via the `AsPrimitive` trait.
254    fn as_cast<N: AsPrimitive>(n: N) -> Self;
255}
256
257/// Allows the high-level conversion of generic types as if `as` was used.
258#[inline(always)]
259pub fn as_cast<U: AsCast, T: AsCast>(t: T) -> U {
260    U::as_cast(t)
261}
262
263macro_rules! as_cast {
264    ($($t:ty, $meth:ident ; )*) => ($(
265        impl AsCast for $t {
266            #[inline(always)]
267            #[allow(clippy::as_underscore)] // reason="intentional due to generic API"
268            fn as_cast<N: AsPrimitive>(n: N) -> $t {
269                n.$meth() as _
270            }
271        }
272    )*);
273}
274
275as_cast!(
276    u8, as_u8 ;
277    u16, as_u16 ;
278    u32, as_u32 ;
279    u64, as_u64 ;
280    u128, as_u128 ;
281    usize, as_usize ;
282    i8, as_i8 ;
283    i16, as_i16 ;
284    i32, as_i32 ;
285    i64, as_i64 ;
286    i128, as_i128 ;
287    isize, as_isize ;
288    f32, as_f32 ;
289    f64, as_f64 ;
290);
291
292#[cfg(feature = "f16")]
293as_cast!(
294    f16, as_f16 ;
295    bf16, as_bf16 ;
296);
297
298// PRIMITIVE
299// ---------
300
301/// Primitive type trait (which all have static lifetimes).
302pub trait Primitive: 'static + fmt::Debug + fmt::Display + AsCast {}
303
304macro_rules! primitive {
305    ($($t:ty)*) => ($(
306        impl Primitive for $t {}
307    )*)
308}
309
310primitive! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize f32 f64 }
311
312#[cfg(feature = "f16")]
313primitive! { f16 bf16 }
314
315// NUMBER
316// ------
317
318/// Numerical type trait.
319pub trait Number:
320    Default +
321    Primitive +
322    // Operations
323    ops::Add<Output=Self> +
324    ops::AddAssign +
325    ops::Div<Output=Self> +
326    ops::DivAssign +
327    ops::Mul<Output=Self> +
328    ops::MulAssign +
329    ops::Rem<Output=Self> +
330    ops::RemAssign +
331    ops::Sub<Output=Self> +
332    ops::SubAssign
333{
334    /// If the number is a signed type.
335    const IS_SIGNED: bool;
336}
337
338macro_rules! number_impl {
339    ($($t:tt $is_signed:literal ; )*) => ($(
340        impl Number for $t {
341            const IS_SIGNED: bool = $is_signed;
342        }
343    )*)
344}
345
346number_impl! {
347    u8 false ;
348    u16 false ;
349    u32 false ;
350    u64 false ;
351    u128 false ;
352    usize false ;
353    i8 true ;
354    i16 true ;
355    i32 true ;
356    i64 true ;
357    i128 true ;
358    isize true ;
359    f32 true ;
360    f64 true ;
361    // f128 true
362}
363
364#[cfg(feature = "f16")]
365number_impl! {
366    f16 true ;
367    bf16 true ;
368}
369
370// INTEGER
371// -------
372
373/// Defines a trait that supports integral operations.
374pub trait Integer:
375    // Basic
376    Number + Eq + Ord +
377    // Operations
378    ops::BitAnd<Output=Self> +
379    ops::BitAndAssign +
380    ops::BitOr<Output=Self> +
381    ops::BitOrAssign +
382    ops::BitXor<Output=Self> +
383    ops::BitXorAssign +
384    ops::Not<Output=Self> +
385    ops::Shl<Self, Output=Self> +
386    ops::Shl<i32, Output=Self> +
387    ops::ShlAssign<i32> +
388    ops::Shr<i32, Output=Self> +
389    ops::ShrAssign<i32> +
390{
391    // CONSTANTS
392    const ZERO: Self;
393    const ONE: Self;
394    const TWO: Self;
395    const MAX: Self;
396    const MIN: Self;
397    const BITS: usize;
398
399    // FUNCTIONS (INHERITED)
400    fn leading_zeros(self) -> u32;
401    fn trailing_zeros(self) -> u32;
402    fn pow(self, exp: u32) -> Self;
403    fn checked_pow(self, exp: u32) -> Option<Self>;
404    fn overflowing_pow(self, exp: u32) -> (Self, bool);
405    fn checked_add(self, i: Self) -> Option<Self>;
406    fn checked_sub(self, i: Self) -> Option<Self>;
407    fn checked_mul(self, i: Self) -> Option<Self>;
408    fn overflowing_add(self, i: Self) -> (Self, bool);
409    fn overflowing_sub(self, i: Self) -> (Self, bool);
410    fn overflowing_mul(self, i: Self) -> (Self, bool);
411    fn wrapping_add(self, i: Self) -> Self;
412    fn wrapping_sub(self, i: Self) -> Self;
413    fn wrapping_mul(self, i: Self) -> Self;
414    fn wrapping_neg(self) -> Self;
415    fn saturating_add(self, i: Self) -> Self;
416    fn saturating_sub(self, i: Self) -> Self;
417    fn saturating_mul(self, i: Self) -> Self;
418
419    /// Get the fast ceiling of the quotient from integer division.
420    /// Not safe, since the remainder can easily overflow.
421    #[inline(always)]
422    fn ceil_divmod(self, y: Self) -> (Self, i32) {
423        let q = self / y;
424        let r = self % y;
425        match r == Self::ZERO {
426            true  => (q, i32::as_cast(r)),
427            false => (q + Self::ONE, i32::as_cast(r) - i32::as_cast(y))
428        }
429    }
430
431    /// Get the fast ceiling of the quotient from integer division.
432    /// Not safe, since the remainder can easily overflow.
433    #[inline(always)]
434    fn ceil_div(self, y: Self) -> Self {
435        self.ceil_divmod(y).0
436    }
437
438    /// Get the fast ceiling modulus from integer division.
439    /// Not safe, since the remainder can easily overflow.
440    #[inline(always)]
441    fn ceil_mod(self, y: Self) -> i32 {
442        self.ceil_divmod(y).1
443    }
444
445    // PROPERTIES
446
447    /// Get the number of bits in a value.
448    #[inline(always)]
449    fn bit_length(self) -> u32 {
450        Self::BITS as u32 - self.leading_zeros()
451    }
452
453    /// Returns true if the least-significant bit is odd.
454    #[inline(always)]
455    fn is_odd(self) -> bool {
456        self & Self::ONE == Self::ONE
457    }
458
459    /// Returns true if the least-significant bit is even.
460    #[inline(always)]
461    fn is_even(self) -> bool {
462        !self.is_odd()
463    }
464
465    /// Get the maximum number of digits before the slice will overflow.
466    ///
467    /// This is effectively the floor(log(2**BITS-1, radix)), but we can
468    /// try to go a bit lower without worrying too much.
469    #[inline(always)]
470    fn overflow_digits(radix: u32) -> usize {
471        // this is heavily optimized for base10 and it's a way under estimate
472        // that said, it's fast and works.
473        if radix <= 16 {
474            mem::size_of::<Self>() * 2 - Self::IS_SIGNED as usize
475        } else {
476            // way under approximation but always works and is fast
477            mem::size_of::<Self>()
478        }
479    }
480}
481
482macro_rules! integer_impl {
483($($t:tt)*) => ($(
484    impl Integer for $t {
485        const ZERO: $t = 0;
486        const ONE: $t = 1;
487        const TWO: $t = 2;
488        const MAX: $t = $t::MAX;
489        const MIN: $t = $t::MIN;
490        const BITS: usize = $t::BITS as usize;
491
492        #[inline(always)]
493        fn leading_zeros(self) -> u32 {
494            $t::leading_zeros(self)
495        }
496
497        #[inline(always)]
498        fn trailing_zeros(self) -> u32 {
499            $t::trailing_zeros(self)
500        }
501
502        #[inline(always)]
503        fn checked_add(self, i: Self) -> Option<Self> {
504            $t::checked_add(self, i)
505        }
506
507        #[inline(always)]
508        fn checked_sub(self, i: Self) -> Option<Self> {
509            $t::checked_sub(self, i)
510        }
511
512        #[inline(always)]
513        fn checked_mul(self, i: Self) -> Option<Self> {
514            $t::checked_mul(self, i)
515        }
516
517        #[inline(always)]
518        fn overflowing_add(self, i: Self) -> (Self, bool) {
519            $t::overflowing_add(self, i)
520        }
521
522        #[inline(always)]
523        fn overflowing_sub(self, i: Self) -> (Self, bool) {
524            $t::overflowing_sub(self, i)
525        }
526
527        #[inline(always)]
528        fn overflowing_mul(self, i: Self) -> (Self, bool) {
529            $t::overflowing_mul(self, i)
530        }
531
532        #[inline(always)]
533        fn wrapping_add(self, i: Self) -> Self {
534            $t::wrapping_add(self, i)
535        }
536
537        #[inline(always)]
538        fn wrapping_sub(self, i: Self) -> Self {
539            $t::wrapping_sub(self, i)
540        }
541
542        #[inline(always)]
543        fn wrapping_mul(self, i: Self) -> Self {
544            $t::wrapping_mul(self, i)
545        }
546
547        #[inline(always)]
548        fn wrapping_neg(self) -> Self {
549            $t::wrapping_neg(self)
550        }
551
552        #[inline(always)]
553        fn pow(self, exp: u32) -> Self {
554            Self::pow(self, exp)
555        }
556
557        #[inline(always)]
558        fn checked_pow(self, exp: u32) -> Option<Self> {
559            Self::checked_pow(self, exp)
560        }
561
562        #[inline(always)]
563        fn overflowing_pow(self, exp: u32) -> (Self, bool) {
564            Self::overflowing_pow(self, exp)
565        }
566
567        #[inline(always)]
568        fn saturating_add(self, i: Self) -> Self {
569            $t::saturating_add(self, i)
570        }
571
572        #[inline(always)]
573        fn saturating_sub(self, i: Self) -> Self {
574            $t::saturating_sub(self, i)
575        }
576
577        #[inline(always)]
578        fn saturating_mul(self, i: Self) -> Self {
579            $t::saturating_mul(self, i)
580        }
581    }
582)*)
583}
584
585integer_impl! { u8 u16 u32 u64 u128 i8 i16 i32 i64 i128 usize isize }
586
587// SIGNED INTEGER
588// --------------
589
590/// Defines a trait that supports signed integral operations.
591pub trait SignedInteger: Integer + ops::Neg<Output = Self> {}
592
593macro_rules! signed_integer_impl {
594($($t:tt)*) => ($(
595    impl SignedInteger for $t {}
596)*)
597}
598
599signed_integer_impl! { i8 i16 i32 i64 i128 isize }
600
601// UNSIGNED INTEGER
602// ----------------
603
604/// Defines a trait that supports unsigned integral operations.
605pub trait UnsignedInteger: Integer {}
606
607macro_rules! unsigned_integer_impl {
608($($t:ty)*) => ($(
609    impl UnsignedInteger for $t {}
610)*)
611}
612
613unsigned_integer_impl! { u8 u16 u32 u64 u128 usize }
614
615// FLOAT
616// -----
617
618/// Float information for native float types.
619#[cfg(feature = "floats")]
620pub trait Float: Number + ops::Neg<Output = Self> {
621    /// Unsigned type of the same size.
622    type Unsigned: UnsignedInteger;
623
624    // CONSTANTS
625    const ZERO: Self;
626    const ONE: Self;
627    const TWO: Self;
628    const MAX: Self;
629    const MIN: Self;
630    const INFINITY: Self;
631    const NEG_INFINITY: Self;
632    const NAN: Self;
633    const BITS: usize;
634
635    /// Bitmask for the sign bit.
636    const SIGN_MASK: Self::Unsigned;
637    /// Bitmask for the exponent, including the hidden bit.
638    const EXPONENT_MASK: Self::Unsigned;
639    /// Bitmask for the hidden bit in exponent, which is an implicit 1 in the
640    /// fraction.
641    const HIDDEN_BIT_MASK: Self::Unsigned;
642    /// Bitmask for the mantissa (fraction), excluding the hidden bit.
643    const MANTISSA_MASK: Self::Unsigned;
644    /// Mask to determine if a full-carry occurred (1 in bit above hidden bit).
645    const CARRY_MASK: Self::Unsigned;
646
647    // PROPERTIES
648
649    // The following constants can be calculated as follows:
650    //  - `INFINITY_BITS`: EXPONENT_MASK
651    //  - `NEGATIVE_INFINITY_BITS`: INFINITY_BITS | SIGN_MASK
652    //  - `EXPONENT_BIAS`: `2^(EXPONENT_SIZE-1) - 1 + MANTISSA_SIZE`
653    //  - `DENORMAL_EXPONENT`: `1 - EXPONENT_BIAS`
654    //  - `MAX_EXPONENT`: `2^EXPONENT_SIZE - 1 - EXPONENT_BIAS`
655
656    /// Positive infinity as bits.
657    const INFINITY_BITS: Self::Unsigned;
658    /// Positive infinity as bits.
659    const NEGATIVE_INFINITY_BITS: Self::Unsigned;
660    /// Size of the exponent.
661    const EXPONENT_SIZE: i32;
662    /// Size of the significand (mantissa) without hidden bit.
663    const MANTISSA_SIZE: i32;
664    /// Bias of the exponent.
665    const EXPONENT_BIAS: i32;
666    /// Exponent portion of a denormal float.
667    const DENORMAL_EXPONENT: i32;
668    /// Maximum exponent value in float.
669    const MAX_EXPONENT: i32;
670
671    // FUNCTIONS (INHERITED)
672
673    // Re-export the to and from bits methods.
674    fn to_bits(self) -> Self::Unsigned;
675    fn from_bits(u: Self::Unsigned) -> Self;
676    fn ln(self) -> Self;
677    fn floor(self) -> Self;
678    fn is_sign_positive(self) -> bool;
679    fn is_sign_negative(self) -> bool;
680
681    /// Returns true if the float is a denormal.
682    #[inline(always)]
683    fn is_denormal(self) -> bool {
684        self.to_bits() & Self::EXPONENT_MASK == Self::Unsigned::ZERO
685    }
686
687    /// Returns true if the float is a NaN or Infinite.
688    #[inline(always)]
689    fn is_special(self) -> bool {
690        self.to_bits() & Self::EXPONENT_MASK == Self::EXPONENT_MASK
691    }
692
693    /// Returns true if the float is NaN.
694    #[inline(always)]
695    fn is_nan(self) -> bool {
696        self.is_special() && (self.to_bits() & Self::MANTISSA_MASK) != Self::Unsigned::ZERO
697    }
698
699    /// Returns true if the float is infinite.
700    #[inline(always)]
701    fn is_inf(self) -> bool {
702        self.is_special() && (self.to_bits() & Self::MANTISSA_MASK) == Self::Unsigned::ZERO
703    }
704
705    /// Returns true if the float's least-significant mantissa bit is odd.
706    #[inline(always)]
707    fn is_odd(self) -> bool {
708        self.to_bits().is_odd()
709    }
710
711    /// Returns true if the float's least-significant mantissa bit is even.
712    #[inline(always)]
713    fn is_even(self) -> bool {
714        !self.is_odd()
715    }
716
717    /// Returns true if the float needs a negative sign when serializing it.
718    ///
719    /// This is true if it's `-0.0` or it's below 0 and not NaN. But inf values
720    /// need the sign.
721    #[inline(always)]
722    fn needs_negative_sign(self) -> bool {
723        self.is_sign_negative() && !self.is_nan()
724    }
725
726    /// Get exponent component from the float.
727    #[inline(always)]
728    fn exponent(self) -> i32 {
729        if self.is_denormal() {
730            return Self::DENORMAL_EXPONENT;
731        }
732
733        let bits = self.to_bits();
734        let biased_e = i32::as_cast((bits & Self::EXPONENT_MASK) >> Self::MANTISSA_SIZE).as_i32();
735        biased_e - Self::EXPONENT_BIAS
736    }
737
738    /// Get mantissa (significand) component from float.
739    #[inline(always)]
740    fn mantissa(self) -> Self::Unsigned {
741        let bits = self.to_bits();
742        let s = bits & Self::MANTISSA_MASK;
743        if !self.is_denormal() {
744            s + Self::HIDDEN_BIT_MASK
745        } else {
746            s
747        }
748    }
749
750    /// Get next greater float.
751    #[inline(always)]
752    fn next(self) -> Self {
753        let bits = self.to_bits();
754        if self.is_sign_negative() && self == Self::ZERO {
755            // -0.0
756            Self::ZERO
757        } else if bits == Self::INFINITY_BITS {
758            Self::from_bits(Self::INFINITY_BITS)
759        } else if self.is_sign_negative() {
760            Self::from_bits(bits.saturating_sub(Self::Unsigned::ONE))
761        } else {
762            Self::from_bits(bits.saturating_add(Self::Unsigned::ONE))
763        }
764    }
765
766    /// Get next greater float for a positive float.
767    /// Value must be >= 0.0 and < INFINITY.
768    #[inline(always)]
769    fn next_positive(self) -> Self {
770        debug_assert!(self.is_sign_positive() && !self.is_inf());
771        Self::from_bits(self.to_bits() + Self::Unsigned::ONE)
772    }
773
774    /// Get previous greater float, such that `self.prev().next() == self`.
775    #[inline(always)]
776    fn prev(self) -> Self {
777        let bits = self.to_bits();
778        if self.is_sign_positive() && self == Self::ZERO {
779            // +0.0
780            -Self::ZERO
781        } else if bits == Self::NEGATIVE_INFINITY_BITS {
782            Self::from_bits(Self::NEGATIVE_INFINITY_BITS)
783        } else if self.is_sign_negative() {
784            Self::from_bits(bits.saturating_add(Self::Unsigned::ONE))
785        } else {
786            Self::from_bits(bits.saturating_sub(Self::Unsigned::ONE))
787        }
788    }
789
790    /// Get previous greater float for a positive float.
791    /// Value must be > 0.0.
792    #[inline(always)]
793    fn prev_positive(self) -> Self {
794        debug_assert!(self.is_sign_positive() && self != Self::ZERO);
795        Self::from_bits(self.to_bits() - Self::Unsigned::ONE)
796    }
797
798    /// Round a positive number to even.
799    #[inline(always)]
800    fn round_positive_even(self) -> Self {
801        if self.mantissa().is_odd() {
802            self.next_positive()
803        } else {
804            self
805        }
806    }
807
808    /// Get the max of two finite numbers.
809    #[inline(always)]
810    fn max_finite(self, f: Self) -> Self {
811        debug_assert!(!self.is_special() && !f.is_special(), "max_finite self={} f={}", self, f);
812        if self < f {
813            f
814        } else {
815            self
816        }
817    }
818
819    /// Get the min of two finite numbers.
820    #[inline(always)]
821    fn min_finite(self, f: Self) -> Self {
822        debug_assert!(!self.is_special() && !f.is_special(), "min_finite self={} f={}", self, f);
823        if self < f {
824            self
825        } else {
826            f
827        }
828    }
829}
830
831/// Define the float literals.
832#[cfg(feature = "floats")]
833macro_rules! float_literals {
834    ($float:ty) => {
835        const ZERO: $float = 0.0;
836        const ONE: $float = 1.0;
837        const TWO: $float = 2.0;
838        const MAX: $float = <$float>::MAX;
839        const MIN: $float = <$float>::MIN;
840        const INFINITY: $float = <$float>::INFINITY;
841        const NEG_INFINITY: $float = <$float>::NEG_INFINITY;
842        const NAN: $float = <$float>::NAN;
843        const BITS: usize = mem::size_of::<$float>() * 8;
844    };
845}
846
847/// Define the float masks.
848#[cfg(feature = "floats")]
849macro_rules! float_masks {
850    (
851        float =>
852        $float:ty,sign_mask =>
853        $sign:literal,exponent_mask =>
854        $exponent:literal,hidden_bit_mask =>
855        $hidden:literal,mantissa_mask =>
856        $mantissa:literal,
857    ) => {
858        const SIGN_MASK: <$float>::Unsigned = $sign;
859        const EXPONENT_MASK: <$float>::Unsigned = $exponent;
860        const HIDDEN_BIT_MASK: <$float>::Unsigned = $hidden;
861        const MANTISSA_MASK: <$float>::Unsigned = $mantissa;
862        // The carry mask is always 1 bit above the hidden bit.
863        const CARRY_MASK: <$float>::Unsigned = $hidden << 1;
864        // Infinity is always every exponent bit set.
865        const INFINITY_BITS: <$float>::Unsigned = $exponent;
866        // Negative infinity is just infinity + sign.
867        const NEGATIVE_INFINITY_BITS: <$float>::Unsigned = $exponent | $sign;
868    };
869}
870
871//  Due to missing specifics or types for the following float types,
872//  `Float` is not yet fully implemented for:
873//      - f128
874
875#[cfg(feature = "f16")]
876macro_rules! float_one {
877    ($f:ident) => {
878        (($f::EXPONENT_BIAS - $f::MANTISSA_SIZE) as u16) << $f::MANTISSA_SIZE
879    };
880}
881
882#[cfg(feature = "f16")]
883macro_rules! float_two {
884    ($f:ident) => {
885        (($f::EXPONENT_BIAS - $f::MANTISSA_SIZE + 1) as u16) << $f::MANTISSA_SIZE
886    };
887}
888
889#[cfg(feature = "f16")]
890macro_rules! float_max {
891    ($f:ident) => {
892        ($f::EXPONENT_MASK ^ $f::HIDDEN_BIT_MASK) | $f::MANTISSA_MASK
893    };
894}
895
896#[cfg(feature = "f16")]
897macro_rules! float_min {
898    ($f:ident) => {
899        $f::MAX.to_bits() | $f::SIGN_MASK
900    };
901}
902
903#[cfg(feature = "f16")]
904macro_rules! float_nan {
905    ($f:ident) => {
906        $f::EXPONENT_MASK | ($f::HIDDEN_BIT_MASK >> 1)
907    };
908}
909
910#[cfg(feature = "f16")]
911impl Float for f16 {
912    type Unsigned = u16;
913
914    const ZERO: Self = Self::from_bits(0);
915    const ONE: Self = Self::from_bits(float_one!(Self));
916    const TWO: Self = Self::from_bits(float_two!(Self));
917    const MAX: Self = Self::from_bits(float_max!(Self));
918    const MIN: Self = Self::from_bits(float_min!(Self));
919    const INFINITY: Self = Self::from_bits(Self::INFINITY_BITS);
920    const NEG_INFINITY: Self = Self::from_bits(Self::NEGATIVE_INFINITY_BITS);
921    const NAN: Self = Self::from_bits(float_nan!(Self));
922    const BITS: usize = mem::size_of::<Self>() * 8;
923
924    float_masks!(
925        float => Self,
926        sign_mask => 0x8000,
927        exponent_mask => 0x7C00,
928        hidden_bit_mask => 0x0400,
929        mantissa_mask => 0x03FF,
930    );
931    const EXPONENT_SIZE: i32 = 5;
932    const MANTISSA_SIZE: i32 = 10;
933    const EXPONENT_BIAS: i32 = 15 + Self::MANTISSA_SIZE;
934    const DENORMAL_EXPONENT: i32 = 1 - Self::EXPONENT_BIAS;
935    const MAX_EXPONENT: i32 = 0x1F - Self::EXPONENT_BIAS;
936
937    #[inline(always)]
938    fn to_bits(self) -> u16 {
939        f16::to_bits(self)
940    }
941
942    #[inline(always)]
943    fn from_bits(u: u16) -> f16 {
944        f16::from_bits(u)
945    }
946
947    #[inline(always)]
948    fn ln(self) -> f16 {
949        f16::from_f32(self.as_f32().ln())
950    }
951
952    #[inline(always)]
953    fn floor(self) -> f16 {
954        f16::from_f32(self.as_f32().floor())
955    }
956
957    #[inline(always)]
958    fn is_sign_positive(self) -> bool {
959        self.to_bits() & Self::SIGN_MASK == 0
960    }
961
962    #[inline(always)]
963    fn is_sign_negative(self) -> bool {
964        !self.is_sign_positive()
965    }
966}
967
968#[cfg(feature = "f16")]
969impl Float for bf16 {
970    type Unsigned = u16;
971
972    const ZERO: Self = Self::from_bits(0);
973    const ONE: Self = Self::from_bits(float_one!(Self));
974    const TWO: Self = Self::from_bits(float_two!(Self));
975    const MAX: Self = Self::from_bits(float_max!(Self));
976    const MIN: Self = Self::from_bits(float_min!(Self));
977    const INFINITY: Self = Self::from_bits(Self::INFINITY_BITS);
978    const NEG_INFINITY: Self = Self::from_bits(Self::NEGATIVE_INFINITY_BITS);
979    const NAN: Self = Self::from_bits(float_nan!(Self));
980    const BITS: usize = mem::size_of::<Self>() * 8;
981
982    float_masks!(
983        float => Self,
984        sign_mask => 0x8000,
985        exponent_mask => 0x7F80,
986        hidden_bit_mask => 0x0080,
987        mantissa_mask => 0x007F,
988    );
989    const EXPONENT_SIZE: i32 = 8;
990    const MANTISSA_SIZE: i32 = 7;
991    const EXPONENT_BIAS: i32 = 127 + Self::MANTISSA_SIZE;
992    const DENORMAL_EXPONENT: i32 = 1 - Self::EXPONENT_BIAS;
993    const MAX_EXPONENT: i32 = 0xFF - Self::EXPONENT_BIAS;
994
995    #[inline(always)]
996    fn to_bits(self) -> u16 {
997        bf16::to_bits(self)
998    }
999
1000    #[inline(always)]
1001    fn from_bits(u: u16) -> bf16 {
1002        bf16::from_bits(u)
1003    }
1004
1005    #[inline(always)]
1006    fn ln(self) -> bf16 {
1007        bf16::from_f32(self.as_f32().ln())
1008    }
1009
1010    #[inline(always)]
1011    fn floor(self) -> bf16 {
1012        bf16::from_f32(self.as_f32().floor())
1013    }
1014
1015    #[inline(always)]
1016    fn is_sign_positive(self) -> bool {
1017        self.to_bits() & Self::SIGN_MASK == 0
1018    }
1019
1020    #[inline(always)]
1021    fn is_sign_negative(self) -> bool {
1022        !self.is_sign_positive()
1023    }
1024}
1025
1026#[cfg(feature = "floats")]
1027impl Float for f32 {
1028    type Unsigned = u32;
1029    float_literals!(f32);
1030    float_masks!(
1031        float => Self,
1032        sign_mask => 0x80000000,
1033        exponent_mask => 0x7F800000,
1034        hidden_bit_mask => 0x00800000,
1035        mantissa_mask => 0x007FFFFF,
1036    );
1037    const EXPONENT_SIZE: i32 = 8;
1038    const MANTISSA_SIZE: i32 = 23;
1039    const EXPONENT_BIAS: i32 = 127 + Self::MANTISSA_SIZE;
1040    const DENORMAL_EXPONENT: i32 = 1 - Self::EXPONENT_BIAS;
1041    const MAX_EXPONENT: i32 = 0xFF - Self::EXPONENT_BIAS;
1042
1043    #[inline(always)]
1044    fn to_bits(self) -> u32 {
1045        f32::to_bits(self)
1046    }
1047
1048    #[inline(always)]
1049    fn from_bits(u: u32) -> f32 {
1050        f32::from_bits(u)
1051    }
1052
1053    #[inline(always)]
1054    fn ln(self) -> f32 {
1055        #[cfg(feature = "std")]
1056        return f32::ln(self);
1057
1058        #[cfg(not(feature = "std"))]
1059        return logf(self);
1060    }
1061
1062    #[inline(always)]
1063    fn floor(self) -> f32 {
1064        #[cfg(feature = "std")]
1065        return f32::floor(self);
1066
1067        #[cfg(not(feature = "std"))]
1068        return floorf(self);
1069    }
1070
1071    #[inline(always)]
1072    fn is_sign_positive(self) -> bool {
1073        f32::is_sign_positive(self)
1074    }
1075
1076    #[inline(always)]
1077    fn is_sign_negative(self) -> bool {
1078        f32::is_sign_negative(self)
1079    }
1080}
1081
1082#[cfg(feature = "floats")]
1083impl Float for f64 {
1084    type Unsigned = u64;
1085    float_literals!(f64);
1086    float_masks!(
1087        float => Self,
1088        sign_mask => 0x8000000000000000,
1089        exponent_mask => 0x7FF0000000000000,
1090        hidden_bit_mask => 0x0010000000000000,
1091        mantissa_mask => 0x000FFFFFFFFFFFFF,
1092    );
1093    const EXPONENT_SIZE: i32 = 11;
1094    const MANTISSA_SIZE: i32 = 52;
1095    const EXPONENT_BIAS: i32 = 1023 + Self::MANTISSA_SIZE;
1096    const DENORMAL_EXPONENT: i32 = 1 - Self::EXPONENT_BIAS;
1097    const MAX_EXPONENT: i32 = 0x7FF - Self::EXPONENT_BIAS;
1098
1099    #[inline(always)]
1100    fn to_bits(self) -> u64 {
1101        f64::to_bits(self)
1102    }
1103
1104    #[inline(always)]
1105    fn from_bits(u: u64) -> f64 {
1106        f64::from_bits(u)
1107    }
1108
1109    #[inline(always)]
1110    fn ln(self) -> f64 {
1111        #[cfg(feature = "std")]
1112        return f64::ln(self);
1113
1114        #[cfg(not(feature = "std"))]
1115        return logd(self);
1116    }
1117
1118    #[inline(always)]
1119    fn floor(self) -> f64 {
1120        #[cfg(feature = "std")]
1121        return f64::floor(self);
1122
1123        #[cfg(not(feature = "std"))]
1124        return floord(self);
1125    }
1126
1127    #[inline(always)]
1128    fn is_sign_positive(self) -> bool {
1129        f64::is_sign_positive(self)
1130    }
1131
1132    #[inline(always)]
1133    fn is_sign_negative(self) -> bool {
1134        f64::is_sign_negative(self)
1135    }
1136}
1137
1138// #[cfg(feature = "f128")]
1139// impl Float for f128 {
1140//     type Unsigned = u128;
1141//     float_literals!(f128);
1142//     float_masks!(
1143//         float => Self,
1144//         sign_mask => 0x80000000000000000000000000000000,
1145//         exponent_mask => 0x7FFF0000000000000000000000000000,
1146//         hidden_bit_mask => 0x00010000000000000000000000000000,
1147//         mantissa_mask => 0x0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF,
1148//     );
1149//     const EXPONENT_SIZE: i32 = 15;
1150//     const MANTISSA_SIZE: i32 = 112;
1151//     const EXPONENT_BIAS: i32 = 16383 + Self::MANTISSA_SIZE;
1152//     const DENORMAL_EXPONENT: i32 = 1 - Self::EXPONENT_BIAS;
1153//     const MAX_EXPONENT: i32 = 0x7FFF - Self::EXPONENT_BIAS;
1154// }
1155
1156// FLOAT HELPERS
1157// -------------
1158
1159// These are adapted from libm, a port of musl libc's libm to Rust.
1160// libm can be found online [here](https://github.com/rust-lang/libm),
1161// and is similarly licensed under an Apache2.0/MIT license
1162
1163/// # Safety
1164///
1165/// Safe as long as `e` is properly initialized.
1166#[cfg(all(not(feature = "std"), feature = "floats"))]
1167macro_rules! volatile {
1168($e:expr) => {
1169    // SAFETY: safe as long as `$e` has been properly initialized.
1170    unsafe {
1171        core::ptr::read_volatile(&$e);
1172    }
1173};
1174}
1175
1176/// Floor (f64)
1177///
1178/// Finds the nearest integer less than or equal to `x`.
1179#[cfg(all(not(feature = "std"), feature = "floats"))]
1180fn floord(x: f64) -> f64 {
1181    const TOINT: f64 = 1. / f64::EPSILON;
1182
1183    let ui = x.to_bits();
1184    let e = ((ui >> 52) & 0x7ff) as i32;
1185
1186    if (e >= 0x3ff + 52) || (x == 0.) {
1187        return x;
1188    }
1189    /* y = int(x) - x, where int(x) is an integer neighbor of x */
1190    let y = if (ui >> 63) != 0 {
1191        x - TOINT + TOINT - x
1192    } else {
1193        x + TOINT - TOINT - x
1194    };
1195    /* special case because of non-nearest rounding modes */
1196    if e < 0x3ff {
1197        volatile!(y);
1198        return if (ui >> 63) != 0 {
1199            -1.
1200        } else {
1201            0.
1202        };
1203    }
1204    if y > 0. {
1205        x + y - 1.
1206    } else {
1207        x + y
1208    }
1209}
1210
1211/// Floor (f32)
1212///
1213/// Finds the nearest integer less than or equal to `x`.
1214#[cfg(all(not(feature = "std"), feature = "floats"))]
1215fn floorf(x: f32) -> f32 {
1216    let mut ui = x.to_bits();
1217    let e = (((ui >> 23) as i32) & 0xff) - 0x7f;
1218
1219    if e >= 23 {
1220        return x;
1221    }
1222    if e >= 0 {
1223        let m: u32 = 0x007fffff >> e;
1224        if (ui & m) == 0 {
1225            return x;
1226        }
1227        volatile!(x + f32::from_bits(0x7b800000));
1228        if ui >> 31 != 0 {
1229            ui += m;
1230        }
1231        ui &= !m;
1232    } else {
1233        volatile!(x + f32::from_bits(0x7b800000));
1234        if ui >> 31 == 0 {
1235            ui = 0;
1236        } else if ui << 1 != 0 {
1237            return -1.0;
1238        }
1239    }
1240    f32::from_bits(ui)
1241}
1242
1243/* origin: FreeBSD /usr/src/lib/msun/src/e_log.c */
1244/*
1245 * ====================================================
1246 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
1247 *
1248 * Developed at SunSoft, a Sun Microsystems, Inc. business.
1249 * Permission to use, copy, modify, and distribute this
1250 * software is freely granted, provided that this notice
1251 * is preserved.
1252 * ====================================================
1253 */
1254/* log(x)
1255 * Return the logarithm of x
1256 *
1257 * Method :
1258 *   1. Argument Reduction: find k and f such that
1259 *                      x = 2^k * (1+f),
1260 *         where  sqrt(2)/2 < 1+f < sqrt(2) .
1261 *
1262 *   2. Approximation of log(1+f).
1263 *      Let s = f/(2+f) ; based on log(1+f) = log(1+s) - log(1-s)
1264 *               = 2s + 2/3 s**3 + 2/5 s**5 + .....,
1265 *               = 2s + s*R
1266 *      We use a special Remez algorithm on [0,0.1716] to generate
1267 *      a polynomial of degree 14 to approximate R The maximum error
1268 *      of this polynomial approximation is bounded by 2**-58.45. In
1269 *      other words,
1270 *                      2      4      6      8      10      12      14
1271 *          R(z) ~ Lg1*s +Lg2*s +Lg3*s +Lg4*s +Lg5*s  +Lg6*s  +Lg7*s
1272 *      (the values of Lg1 to Lg7 are listed in the program)
1273 *      and
1274 *          |      2          14          |     -58.45
1275 *          | Lg1*s +...+Lg7*s    -  R(z) | <= 2
1276 *          |                             |
1277 *      Note that 2s = f - s*f = f - hfsq + s*hfsq, where hfsq = f*f/2.
1278 *      In order to guarantee error in log below 1ulp, we compute log
1279 *      by
1280 *              log(1+f) = f - s*(f - R)        (if f is not too large)
1281 *              log(1+f) = f - (hfsq - s*(hfsq+R)).     (better accuracy)
1282 *
1283 *      3. Finally,  log(x) = k*ln2 + log(1+f).
1284 *                          = k*ln2_hi+(f-(hfsq-(s*(hfsq+R)+k*ln2_lo)))
1285 *         Here ln2 is split into two floating point number:
1286 *                      ln2_hi + ln2_lo,
1287 *         where n*ln2_hi is always exact for |n| < 2000.
1288 *
1289 * Special cases:
1290 *      log(x) is NaN with signal if x < 0 (including -INF) ;
1291 *      log(+INF) is +INF; log(0) is -INF with signal;
1292 *      log(NaN) is that NaN with no signal.
1293 *
1294 * Accuracy:
1295 *      according to an error analysis, the error is always less than
1296 *      1 ulp (unit in the last place).
1297 *
1298 * Constants:
1299 * The hexadecimal values are the intended ones for the following
1300 * constants. The decimal values may be used, provided that the
1301 * compiler will convert from decimal to binary accurately enough
1302 * to produce the hexadecimal values shown.
1303 */
1304
1305#[allow(clippy::eq_op, clippy::excessive_precision)] // reason="values need to be exact under all conditions"
1306#[cfg(all(not(feature = "std"), feature = "floats"))]
1307fn logd(mut x: f64) -> f64 {
1308    const LN2_HI: f64 = 6.93147180369123816490e-01; /* 3fe62e42 fee00000 */
1309    const LN2_LO: f64 = 1.90821492927058770002e-10; /* 3dea39ef 35793c76 */
1310    const LG1: f64 = 6.666666666666735130e-01; /* 3FE55555 55555593 */
1311    const LG2: f64 = 3.999999999940941908e-01; /* 3FD99999 9997FA04 */
1312    const LG3: f64 = 2.857142874366239149e-01; /* 3FD24924 94229359 */
1313    const LG4: f64 = 2.222219843214978396e-01; /* 3FCC71C5 1D8E78AF */
1314    const LG5: f64 = 1.818357216161805012e-01; /* 3FC74664 96CB03DE */
1315    const LG6: f64 = 1.531383769920937332e-01; /* 3FC39A09 D078C69F */
1316    const LG7: f64 = 1.479819860511658591e-01; /* 3FC2F112 DF3E5244 */
1317
1318    let x1p54 = f64::from_bits(0x4350000000000000); // 0x1p54 === 2 ^ 54
1319
1320    let mut ui = x.to_bits();
1321    let mut hx: u32 = (ui >> 32) as u32;
1322    let mut k: i32 = 0;
1323
1324    if (hx < 0x00100000) || ((hx >> 31) != 0) {
1325        /* x < 2**-126 */
1326        if ui << 1 == 0 {
1327            return -1. / (x * x); /* log(+-0)=-inf */
1328        }
1329        if hx >> 31 != 0 {
1330            return (x - x) / 0.0; /* log(-#) = NaN */
1331        }
1332        /* subnormal number, scale x up */
1333        k -= 54;
1334        x *= x1p54;
1335        ui = x.to_bits();
1336        hx = (ui >> 32) as u32;
1337    } else if hx >= 0x7ff00000 {
1338        return x;
1339    } else if hx == 0x3ff00000 && ui << 32 == 0 {
1340        return 0.;
1341    }
1342
1343    /* reduce x into [sqrt(2)/2, sqrt(2)] */
1344    hx += 0x3ff00000 - 0x3fe6a09e;
1345    k += ((hx >> 20) as i32) - 0x3ff;
1346    hx = (hx & 0x000fffff) + 0x3fe6a09e;
1347    ui = ((hx as u64) << 32) | (ui & 0xffffffff);
1348    x = f64::from_bits(ui);
1349
1350    let f: f64 = x - 1.0;
1351    let hfsq: f64 = 0.5 * f * f;
1352    let s: f64 = f / (2.0 + f);
1353    let z: f64 = s * s;
1354    let w: f64 = z * z;
1355    let t1: f64 = w * (LG2 + w * (LG4 + w * LG6));
1356    let t2: f64 = z * (LG1 + w * (LG3 + w * (LG5 + w * LG7)));
1357    let r: f64 = t2 + t1;
1358    let dk: f64 = k as f64;
1359    s * (hfsq + r) + dk * LN2_LO - hfsq + f + dk * LN2_HI
1360}
1361
1362/* origin: FreeBSD /usr/src/lib/msun/src/e_logf.c */
1363/*
1364 * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
1365 */
1366/*
1367 * ====================================================
1368 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
1369 *
1370 * Developed at SunPro, a Sun Microsystems, Inc. business.
1371 * Permission to use, copy, modify, and distribute this
1372 * software is freely granted, provided that this notice
1373 * is preserved.
1374 * ====================================================
1375 */
1376
1377#[allow(clippy::eq_op, clippy::excessive_precision)] // reason="values need to be exact under all conditions"
1378#[cfg(all(not(feature = "std"), feature = "floats"))]
1379fn logf(mut x: f32) -> f32 {
1380    const LN2_HI: f32 = 6.9313812256e-01; /* 0x3f317180 */
1381    const LN2_LO: f32 = 9.0580006145e-06; /* 0x3717f7d1 */
1382    /* |(log(1+s)-log(1-s))/s - Lg(s)| < 2**-34.24 (~[-4.95e-11, 4.97e-11]). */
1383    const LG1: f32 = 0.66666662693; /* 0xaaaaaa.0p-24 */
1384    const LG2: f32 = 0.40000972152; /* 0xccce13.0p-25 */
1385    const LG3: f32 = 0.28498786688; /* 0x91e9ee.0p-25 */
1386    const LG4: f32 = 0.24279078841; /* 0xf89e26.0p-26 */
1387
1388    let x1p25 = f32::from_bits(0x4c000000); // 0x1p25f === 2 ^ 25
1389
1390    let mut ix = x.to_bits();
1391    let mut k = 0i32;
1392
1393    if (ix < 0x00800000) || ((ix >> 31) != 0) {
1394        /* x < 2**-126 */
1395        if ix << 1 == 0 {
1396            return -1. / (x * x); /* log(+-0)=-inf */
1397        }
1398        if (ix >> 31) != 0 {
1399            return (x - x) / 0.; /* log(-#) = NaN */
1400        }
1401        /* subnormal number, scale up x */
1402        k -= 25;
1403        x *= x1p25;
1404        ix = x.to_bits();
1405    } else if ix >= 0x7f800000 {
1406        return x;
1407    } else if ix == 0x3f800000 {
1408        return 0.;
1409    }
1410
1411    /* reduce x into [sqrt(2)/2, sqrt(2)] */
1412    ix += 0x3f800000 - 0x3f3504f3;
1413    k += ((ix >> 23) as i32) - 0x7f;
1414    ix = (ix & 0x007fffff) + 0x3f3504f3;
1415    x = f32::from_bits(ix);
1416
1417    let f = x - 1.;
1418    let s = f / (2. + f);
1419    let z = s * s;
1420    let w = z * z;
1421    let t1 = w * (LG2 + w * LG4);
1422    let t2 = z * (LG1 + w * LG3);
1423    let r = t2 + t1;
1424    let hfsq = 0.5 * f * f;
1425    let dk = k as f32;
1426    s * (hfsq + r) + dk * LN2_LO - hfsq + f + dk * LN2_HI
1427}