lexical_parse_float/
float.rs1#![doc(hidden)]
7
8#[cfg(all(not(feature = "std"), feature = "compact"))]
9use crate::libm::{powd, powf};
10use crate::limits::{ExactFloat, MaxDigits};
11#[cfg(not(feature = "compact"))]
12use crate::table::{get_small_f32_power, get_small_f64_power, get_small_int_power};
13#[cfg(feature = "f16")]
14use lexical_util::bf16::bf16;
15use lexical_util::extended_float::ExtendedFloat;
16#[cfg(feature = "f16")]
17use lexical_util::f16::f16;
18use lexical_util::num::{AsCast, Float};
19
20pub type ExtendedFloat80 = ExtendedFloat<u64>;
24
25pub trait RawFloat: Float + ExactFloat + MaxDigits {
27 const MAX_MANTISSA_FAST_PATH: u64 = 2_u64 << Self::MANTISSA_SIZE;
29
30 const INFINITE_POWER: i32 = Self::MAX_EXPONENT + Self::EXPONENT_BIAS;
32
33 #[inline(always)]
36 fn min_exponent_fast_path(radix: u32) -> i64 {
37 Self::exponent_limit(radix).0
38 }
39
40 #[inline(always)]
43 fn max_exponent_fast_path(radix: u32) -> i64 {
44 Self::exponent_limit(radix).1
45 }
46
47 #[inline(always)]
50 fn max_exponent_disguised_fast_path(radix: u32) -> i64 {
51 Self::max_exponent_fast_path(radix) + Self::mantissa_limit(radix)
52 }
53
54 unsafe fn pow_fast_path(exponent: usize, radix: u32) -> Self;
60
61 #[inline(always)]
67 unsafe fn int_pow_fast_path(exponent: usize, radix: u32) -> u64 {
68 #[cfg(not(feature = "compact"))]
70 return unsafe { get_small_int_power(exponent, radix) };
71
72 #[cfg(feature = "compact")]
73 return (radix as u64).wrapping_pow(exponent as u32);
74 }
75}
76
77impl RawFloat for f32 {
78 #[inline(always)]
79 unsafe fn pow_fast_path(exponent: usize, radix: u32) -> Self {
80 #[cfg(not(feature = "compact"))]
82 return unsafe { get_small_f32_power(exponent, radix) };
83
84 #[cfg(feature = "compact")]
85 return powf(radix as f32, exponent as f32);
86 }
87}
88
89impl RawFloat for f64 {
90 #[inline(always)]
91 unsafe fn pow_fast_path(exponent: usize, radix: u32) -> Self {
92 #[cfg(not(feature = "compact"))]
94 return unsafe { get_small_f64_power(exponent, radix) };
95
96 #[cfg(feature = "compact")]
97 return powd(radix as f64, exponent as f64);
98 }
99}
100
101#[cfg(feature = "f16")]
102impl RawFloat for f16 {
103 #[inline(always)]
104 unsafe fn pow_fast_path(_: usize, _: u32) -> Self {
105 unimplemented!()
106 }
107}
108
109#[cfg(feature = "f16")]
110impl RawFloat for bf16 {
111 #[inline(always)]
112 unsafe fn pow_fast_path(_: usize, _: u32) -> Self {
113 unimplemented!()
114 }
115}
116
117pub trait LemireFloat: RawFloat {
119 const MIN_EXPONENT_ROUND_TO_EVEN: i32;
138 const MAX_EXPONENT_ROUND_TO_EVEN: i32;
139
140 const MINIMUM_EXPONENT: i32;
142
143 const SMALLEST_POWER_OF_TEN: i32;
145
146 const LARGEST_POWER_OF_TEN: i32;
148}
149
150impl LemireFloat for f32 {
151 const MIN_EXPONENT_ROUND_TO_EVEN: i32 = -17;
152 const MAX_EXPONENT_ROUND_TO_EVEN: i32 = 10;
153 const MINIMUM_EXPONENT: i32 = -127;
154 const SMALLEST_POWER_OF_TEN: i32 = -65;
155 const LARGEST_POWER_OF_TEN: i32 = 38;
156}
157
158impl LemireFloat for f64 {
159 const MIN_EXPONENT_ROUND_TO_EVEN: i32 = -4;
160 const MAX_EXPONENT_ROUND_TO_EVEN: i32 = 23;
161 const MINIMUM_EXPONENT: i32 = -1023;
162 const SMALLEST_POWER_OF_TEN: i32 = -342;
163 const LARGEST_POWER_OF_TEN: i32 = 308;
164}
165
166#[cfg(feature = "f16")]
167impl LemireFloat for f16 {
168 const MIN_EXPONENT_ROUND_TO_EVEN: i32 = 0;
169 const MAX_EXPONENT_ROUND_TO_EVEN: i32 = 0;
170 const MINIMUM_EXPONENT: i32 = 0;
171 const SMALLEST_POWER_OF_TEN: i32 = 0;
172 const LARGEST_POWER_OF_TEN: i32 = 0;
173}
174
175#[cfg(feature = "f16")]
176impl LemireFloat for bf16 {
177 const MIN_EXPONENT_ROUND_TO_EVEN: i32 = 0;
178 const MAX_EXPONENT_ROUND_TO_EVEN: i32 = 0;
179 const MINIMUM_EXPONENT: i32 = 0;
180 const SMALLEST_POWER_OF_TEN: i32 = 0;
181 const LARGEST_POWER_OF_TEN: i32 = 0;
182}
183
184#[inline(always)]
185#[cfg(all(feature = "std", feature = "compact"))]
186pub fn powf(x: f32, y: f32) -> f32 {
187 x.powf(y)
188}
189
190#[inline(always)]
191#[cfg(all(feature = "std", feature = "compact"))]
192pub fn powd(x: f64, y: f64) -> f64 {
193 x.powf(y)
194}
195
196#[inline(always)]
198pub fn extended_to_float<F: Float>(x: ExtendedFloat80) -> F {
199 let mut word = x.mant;
200 word |= (x.exp as u64) << F::MANTISSA_SIZE;
201 F::from_bits(F::Unsigned::as_cast(word))
202}