1//! Numeric traits used for internal implementations.
23#![doc(hidden)]
4#![unstable(
5 feature = "num_internals",
6 reason = "internal routines only exposed for testing",
7 issue = "none"
8)]
910use crate::num::FpCategory;
11use crate::{f64, fmt, ops};
1213/// Lossy `as` casting between two types.
14pub trait CastInto<T: Copy>: Copy {
15fn cast(self) -> T;
16}
1718/// Collection of traits that allow us to be generic over integer size.
19pub trait Int:
20Sized21 + Clone22 + Copy23 + fmt::Debug24 + ops::Shr<u32, Output = Self>
25 + ops::Shl<u32, Output = Self>
26 + ops::BitAnd<Output = Self>
27 + ops::BitOr<Output = Self>
28 + PartialEq29 + CastInto<i16>
30{
31const ZERO: Self;
32const ONE: Self;
33}
3435macro_rules!int {
36 ($($ty:ty),+) => {
37 $(
38impl CastInto<i16> for $ty {
39fn cast(self) -> i16 {
40self as i16
41 }
42 }
4344impl Int for $ty {
45const ZERO: Self = 0;
46const ONE: Self = 1;
47 }
48 )+
49 }
50}
5152impl CastInto<i16> for u64 {
fn cast(self) -> i16 { self as i16 }
}
impl Int for u64 {
const ZERO: Self = 0;
const ONE: Self = 1;
}int!(u16, u32, u64);
5354/// A helper trait to avoid duplicating basically all the conversion code for IEEE floats.
55#[doc(hidden)]
56pub trait Float:
57Sized58 + ops::Div<Output = Self>
59 + ops::Neg<Output = Self>
60 + ops::Mul<Output = Self>
61 + ops::Add<Output = Self>
62 + fmt::Debug63 + PartialEq64 + PartialOrd65 + Default66 + Clone67 + Copy68{
69/// The unsigned integer with the same size as the float
70type Int: Int + Into<u64>;
7172/* general constants */
7374const INFINITY: Self;
75const NEG_INFINITY: Self;
76const NAN: Self;
77const NEG_NAN: Self;
7879/// Bit width of the float
80const BITS: u32;
8182/// The number of bits in the significand, *including* the hidden bit.
83const SIG_TOTAL_BITS: u32;
8485const EXP_MASK: Self::Int;
86const SIG_MASK: Self::Int;
8788/// The number of bits in the significand, *excluding* the hidden bit.
89const SIG_BITS: u32 = Self::SIG_TOTAL_BITS - 1;
9091/// Number of bits in the exponent.
92const EXP_BITS: u32 = Self::BITS - Self::SIG_BITS - 1;
9394/// The saturated (maximum bitpattern) value of the exponent, i.e. the infinite
95 /// representation.
96 ///
97 /// This shifted fully right, use `EXP_MASK` for the shifted value.
98const EXP_SAT: u32 = (1 << Self::EXP_BITS) - 1;
99100/// Signed version of `EXP_SAT` since we convert a lot.
101const INFINITE_POWER: i32 = Self::EXP_SATas i32;
102103/// The exponent bias value. This is also the maximum value of the exponent.
104const EXP_BIAS: u32 = Self::EXP_SAT >> 1;
105106/// Minimum exponent value of normal values.
107const EXP_MIN: i32 = -(Self::EXP_BIASas i32 - 1);
108109/// Round-to-even only happens for negative values of q
110 /// when q ≥ −4 in the 64-bit case and when q ≥ −17 in
111 /// the 32-bit case.
112 ///
113 /// When q ≥ 0,we have that 5^q ≤ 2m+1. In the 64-bit case,we
114 /// have 5^q ≤ 2m+1 ≤ 2^54 or q ≤ 23. In the 32-bit case,we have
115 /// 5^q ≤ 2m+1 ≤ 2^25 or q ≤ 10.
116 ///
117 /// When q < 0, we have w ≥ (2m+1)×5^−q. We must have that w < 2^64
118 /// so (2m+1)×5^−q < 2^64. We have that 2m+1 > 2^53 (64-bit case)
119 /// or 2m+1 > 2^24 (32-bit case). Hence,we must have 2^53×5^−q < 2^64
120 /// (64-bit) and 2^24×5^−q < 2^64 (32-bit). Hence we have 5^−q < 2^11
121 /// or q ≥ −4 (64-bit case) and 5^−q < 2^40 or q ≥ −17 (32-bit case).
122 ///
123 /// Thus we have that we only need to round ties to even when
124 /// we have that q ∈ [−4,23](in the 64-bit case) or q∈[−17,10]
125 /// (in the 32-bit case). In both cases,the power of five(5^|q|)
126 /// fits in a 64-bit word.
127const MIN_EXPONENT_ROUND_TO_EVEN: i32;
128const MAX_EXPONENT_ROUND_TO_EVEN: i32;
129130/// Largest decimal exponent for a non-infinite value.
131 ///
132 /// This is the max exponent in binary converted to the max exponent in decimal. Allows fast
133 /// pathing anything larger than `10^LARGEST_POWER_OF_TEN`, which will round to infinity.
134const LARGEST_POWER_OF_TEN: i32 = {
135let largest_pow2 = Self::EXP_BIAS + 1;
136pow2_to_pow10(largest_pow2as i64) as i32137 };
138139/// Smallest decimal exponent for a non-zero value. This allows for fast pathing anything
140 /// smaller than `10^SMALLEST_POWER_OF_TEN`, which will round to zero.
141 ///
142 /// The smallest power of ten is represented by `⌊log10(2^-n / (2^64 - 1))⌋`, where `n` is
143 /// the smallest power of two. The `2^64 - 1)` denominator comes from the number of values
144 /// that are representable by the intermediate storage format. I don't actually know _why_
145 /// the storage format is relevant here.
146 ///
147 /// The values may be calculated using the formula. Unfortunately we cannot calculate them at
148 /// compile time since intermediates exceed the range of an `f64`.
149const SMALLEST_POWER_OF_TEN: i32;
150151/// Returns the category that this number falls into.
152fn classify(self) -> FpCategory;
153154/// Transmute to the integer representation
155fn to_bits(self) -> Self::Int;
156}
157158/// Items that ideally would be on `Float`, but don't apply to all float types because they
159/// rely on the mantissa fitting into a `u64` (which isn't true for `f128`).
160#[doc(hidden)]
161pub trait FloatExt: Float {
162/// Performs a raw transmutation from an integer.
163fn from_u64_bits(v: u64) -> Self;
164165/// Returns the mantissa, exponent and sign as integers.
166 ///
167 /// This returns `(m, p, s)` such that `s * m * 2^p` represents the original float. For 0, the
168 /// exponent will be `-(EXP_BIAS + SIG_BITS)`, which is the minimum subnormal power. For
169 /// infinity or NaN, the exponent will be `EXP_SAT - EXP_BIAS - SIG_BITS`.
170 ///
171 /// If subnormal, the mantissa will be shifted one bit to the left. Otherwise, it is returned
172 /// with the explicit bit set but otherwise unshifted
173 ///
174 /// `s` is only ever +/-1.
175fn integer_decode(self) -> (u64, i16, i8) {
176let bits = self.to_bits();
177let sign: i8 = if bits >> (Self::BITS - 1) == Self::Int::ZERO { 1 } else { -1 };
178let mut exponent: i16 = ((bits & Self::EXP_MASK) >> Self::SIG_BITS).cast();
179let mantissa = if exponent == 0 {
180 (bits & Self::SIG_MASK) << 1
181} else {
182 (bits & Self::SIG_MASK) | (Self::Int::ONE << Self::SIG_BITS)
183 };
184// Exponent bias + mantissa shift
185exponent -= (Self::EXP_BIAS + Self::SIG_BITS) as i16;
186 (mantissa.into(), exponent, sign)
187 }
188}
189190/// Solve for `b` in `10^b = 2^a`
191const fn pow2_to_pow10(a: i64) -> i64 {
192let res = (aas f64) / f64::consts::LOG2_10;
193resas i64194}
195196#[cfg(target_has_reliable_f16)]
197impl Floatfor f16 {
198type Int = u16;
199200const INFINITY: Self = Self::INFINITY;
201const NEG_INFINITY: Self = Self::NEG_INFINITY;
202const NAN: Self = Self::NAN;
203const NEG_NAN: Self = -Self::NAN;
204205const BITS: u32 = 16;
206const SIG_TOTAL_BITS: u32 = Self::MANTISSA_DIGITS;
207const EXP_MASK: Self::Int = Self::EXP_MASK;
208const SIG_MASK: Self::Int = Self::MAN_MASK;
209210const MIN_EXPONENT_ROUND_TO_EVEN: i32 = -22;
211const MAX_EXPONENT_ROUND_TO_EVEN: i32 = 5;
212const SMALLEST_POWER_OF_TEN: i32 = -27;
213214fn to_bits(self) -> Self::Int {
215self.to_bits()
216 }
217218fn classify(self) -> FpCategory {
219self.classify()
220 }
221}
222223#[cfg(target_has_reliable_f16)]
224impl FloatExtfor f16 {
225#[inline]
226fn from_u64_bits(v: u64) -> Self {
227Self::from_bits((v & 0xFFFF) as u16)
228 }
229}
230231impl Floatfor f32 {
232type Int = u32;
233234const INFINITY: Self = f32::INFINITY;
235const NEG_INFINITY: Self = f32::NEG_INFINITY;
236const NAN: Self = f32::NAN;
237const NEG_NAN: Self = -f32::NAN;
238239const BITS: u32 = 32;
240const SIG_TOTAL_BITS: u32 = Self::MANTISSA_DIGITS;
241const EXP_MASK: Self::Int = Self::EXP_MASK;
242const SIG_MASK: Self::Int = Self::MAN_MASK;
243244const MIN_EXPONENT_ROUND_TO_EVEN: i32 = -17;
245const MAX_EXPONENT_ROUND_TO_EVEN: i32 = 10;
246const SMALLEST_POWER_OF_TEN: i32 = -65;
247248fn to_bits(self) -> Self::Int {
249self.to_bits()
250 }
251252fn classify(self) -> FpCategory {
253self.classify()
254 }
255}
256257impl FloatExtfor f32 {
258#[inline]
259fn from_u64_bits(v: u64) -> Self {
260f32::from_bits((v & 0xFFFFFFFF) as u32)
261 }
262}
263264impl Floatfor f64 {
265type Int = u64;
266267const INFINITY: Self = Self::INFINITY;
268const NEG_INFINITY: Self = Self::NEG_INFINITY;
269const NAN: Self = Self::NAN;
270const NEG_NAN: Self = -Self::NAN;
271272const BITS: u32 = 64;
273const SIG_TOTAL_BITS: u32 = Self::MANTISSA_DIGITS;
274const EXP_MASK: Self::Int = Self::EXP_MASK;
275const SIG_MASK: Self::Int = Self::MAN_MASK;
276277const MIN_EXPONENT_ROUND_TO_EVEN: i32 = -4;
278const MAX_EXPONENT_ROUND_TO_EVEN: i32 = 23;
279const SMALLEST_POWER_OF_TEN: i32 = -342;
280281fn to_bits(self) -> Self::Int {
282self.to_bits()
283 }
284285fn classify(self) -> FpCategory {
286self.classify()
287 }
288}
289290impl FloatExtfor f64 {
291#[inline]
292fn from_u64_bits(v: u64) -> Self {
293f64::from_bits(v)
294 }
295}