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