#![doc(hidden)]
use lexical_util::assert::debug_assert_radix;
#[cfg(feature = "f16")]
use lexical_util::bf16::bf16;
#[cfg(feature = "f16")]
use lexical_util::f16::f16;
#[doc(hidden)]
pub trait ExactFloat {
fn exponent_limit(radix: u32) -> (i64, i64);
fn mantissa_limit(radix: u32) -> i64;
}
impl ExactFloat for f32 {
#[inline(always)]
fn exponent_limit(radix: u32) -> (i64, i64) {
debug_assert_radix(radix);
f32_exponent_limit(radix)
}
#[inline(always)]
fn mantissa_limit(radix: u32) -> i64 {
debug_assert_radix(radix);
f32_mantissa_limit(radix)
}
}
impl ExactFloat for f64 {
#[inline(always)]
fn exponent_limit(radix: u32) -> (i64, i64) {
debug_assert_radix(radix);
f64_exponent_limit(radix)
}
#[inline(always)]
fn mantissa_limit(radix: u32) -> i64 {
debug_assert_radix(radix);
f64_mantissa_limit(radix)
}
}
#[cfg(feature = "f16")]
impl ExactFloat for f16 {
#[inline(always)]
fn exponent_limit(_: u32) -> (i64, i64) {
unimplemented!()
}
#[inline(always)]
fn mantissa_limit(_: u32) -> i64 {
unimplemented!()
}
}
#[cfg(feature = "f16")]
impl ExactFloat for bf16 {
#[inline(always)]
fn exponent_limit(_: u32) -> (i64, i64) {
unimplemented!()
}
#[inline(always)]
fn mantissa_limit(_: u32) -> i64 {
unimplemented!()
}
}
#[inline(always)]
pub const fn f32_exponent_limit(radix: u32) -> (i64, i64) {
match radix {
2 if cfg!(feature = "power-of-two") => (-127, 127),
3 if cfg!(feature = "radix") => (-15, 15),
4 if cfg!(feature = "power-of-two") => (-63, 63),
5 if cfg!(feature = "radix") => (-10, 10),
6 if cfg!(feature = "radix") => (-15, 15),
7 if cfg!(feature = "radix") => (-8, 8),
8 if cfg!(feature = "power-of-two") => (-42, 42),
9 if cfg!(feature = "radix") => (-7, 7),
10 => (-10, 10),
11 if cfg!(feature = "radix") => (-6, 6),
12 if cfg!(feature = "radix") => (-15, 15),
13 if cfg!(feature = "radix") => (-6, 6),
14 if cfg!(feature = "radix") => (-8, 8),
15 if cfg!(feature = "radix") => (-6, 6),
16 if cfg!(feature = "power-of-two") => (-31, 31),
17 if cfg!(feature = "radix") => (-5, 5),
18 if cfg!(feature = "radix") => (-7, 7),
19 if cfg!(feature = "radix") => (-5, 5),
20 if cfg!(feature = "radix") => (-10, 10),
21 if cfg!(feature = "radix") => (-5, 5),
22 if cfg!(feature = "radix") => (-6, 6),
23 if cfg!(feature = "radix") => (-5, 5),
24 if cfg!(feature = "radix") => (-15, 15),
25 if cfg!(feature = "radix") => (-5, 5),
26 if cfg!(feature = "radix") => (-6, 6),
27 if cfg!(feature = "radix") => (-5, 5),
28 if cfg!(feature = "radix") => (-8, 8),
29 if cfg!(feature = "radix") => (-4, 4),
30 if cfg!(feature = "radix") => (-6, 6),
31 if cfg!(feature = "radix") => (-4, 4),
32 if cfg!(feature = "power-of-two") => (-25, 25),
33 if cfg!(feature = "radix") => (-4, 4),
34 if cfg!(feature = "radix") => (-5, 5),
35 if cfg!(feature = "radix") => (-4, 4),
36 if cfg!(feature = "radix") => (-7, 7),
_ => (0, 0),
}
}
#[inline(always)]
pub const fn f32_mantissa_limit(radix: u32) -> i64 {
match radix {
2 if cfg!(feature = "power-of-two") => 24,
3 if cfg!(feature = "radix") => 15,
4 if cfg!(feature = "power-of-two") => 12,
5 if cfg!(feature = "radix") => 10,
6 if cfg!(feature = "radix") => 9,
7 if cfg!(feature = "radix") => 8,
8 if cfg!(feature = "power-of-two") => 8,
9 if cfg!(feature = "radix") => 7,
10 => 7,
11 if cfg!(feature = "radix") => 6,
12 if cfg!(feature = "radix") => 6,
13 if cfg!(feature = "radix") => 6,
14 if cfg!(feature = "radix") => 6,
15 if cfg!(feature = "radix") => 6,
16 if cfg!(feature = "power-of-two") => 6,
17 if cfg!(feature = "radix") => 5,
18 if cfg!(feature = "radix") => 5,
19 if cfg!(feature = "radix") => 5,
20 if cfg!(feature = "radix") => 5,
21 if cfg!(feature = "radix") => 5,
22 if cfg!(feature = "radix") => 5,
23 if cfg!(feature = "radix") => 5,
24 if cfg!(feature = "radix") => 5,
25 if cfg!(feature = "radix") => 5,
26 if cfg!(feature = "radix") => 5,
27 if cfg!(feature = "radix") => 5,
28 if cfg!(feature = "radix") => 4,
29 if cfg!(feature = "radix") => 4,
30 if cfg!(feature = "radix") => 4,
31 if cfg!(feature = "radix") => 4,
32 if cfg!(feature = "power-of-two") => 4,
33 if cfg!(feature = "radix") => 4,
34 if cfg!(feature = "radix") => 4,
35 if cfg!(feature = "radix") => 4,
36 if cfg!(feature = "radix") => 4,
_ => 0,
}
}
#[inline(always)]
pub const fn f64_exponent_limit(radix: u32) -> (i64, i64) {
match radix {
2 if cfg!(feature = "power-of-two") => (-1023, 1023),
3 if cfg!(feature = "radix") => (-33, 33),
4 if cfg!(feature = "power-of-two") => (-511, 511),
5 if cfg!(feature = "radix") => (-22, 22),
6 if cfg!(feature = "radix") => (-33, 33),
7 if cfg!(feature = "radix") => (-18, 18),
8 if cfg!(feature = "power-of-two") => (-341, 341),
9 if cfg!(feature = "radix") => (-16, 16),
10 => (-22, 22),
11 if cfg!(feature = "radix") => (-15, 15),
12 if cfg!(feature = "radix") => (-33, 33),
13 if cfg!(feature = "radix") => (-14, 14),
14 if cfg!(feature = "radix") => (-18, 18),
15 if cfg!(feature = "radix") => (-13, 13),
16 if cfg!(feature = "power-of-two") => (-255, 255),
17 if cfg!(feature = "radix") => (-12, 12),
18 if cfg!(feature = "radix") => (-16, 16),
19 if cfg!(feature = "radix") => (-12, 12),
20 if cfg!(feature = "radix") => (-22, 22),
21 if cfg!(feature = "radix") => (-12, 12),
22 if cfg!(feature = "radix") => (-15, 15),
23 if cfg!(feature = "radix") => (-11, 11),
24 if cfg!(feature = "radix") => (-33, 33),
25 if cfg!(feature = "radix") => (-11, 11),
26 if cfg!(feature = "radix") => (-14, 14),
27 if cfg!(feature = "radix") => (-11, 11),
28 if cfg!(feature = "radix") => (-18, 18),
29 if cfg!(feature = "radix") => (-10, 10),
30 if cfg!(feature = "radix") => (-13, 13),
31 if cfg!(feature = "radix") => (-10, 10),
32 if cfg!(feature = "power-of-two") => (-204, 204),
33 if cfg!(feature = "radix") => (-10, 10),
34 if cfg!(feature = "radix") => (-12, 12),
35 if cfg!(feature = "radix") => (-10, 10),
36 if cfg!(feature = "radix") => (-16, 16),
_ => (0, 0),
}
}
#[inline(always)]
pub const fn f64_mantissa_limit(radix: u32) -> i64 {
match radix {
2 if cfg!(feature = "power-of-two") => 53,
3 if cfg!(feature = "radix") => 33,
4 if cfg!(feature = "power-of-two") => 26,
5 if cfg!(feature = "radix") => 22,
6 if cfg!(feature = "radix") => 20,
7 if cfg!(feature = "radix") => 18,
8 if cfg!(feature = "power-of-two") => 17,
9 if cfg!(feature = "radix") => 16,
10 => 15,
11 if cfg!(feature = "radix") => 15,
12 if cfg!(feature = "radix") => 14,
13 if cfg!(feature = "radix") => 14,
14 if cfg!(feature = "radix") => 13,
15 if cfg!(feature = "radix") => 13,
16 if cfg!(feature = "power-of-two") => 13,
17 if cfg!(feature = "radix") => 12,
18 if cfg!(feature = "radix") => 12,
19 if cfg!(feature = "radix") => 12,
20 if cfg!(feature = "radix") => 12,
21 if cfg!(feature = "radix") => 12,
22 if cfg!(feature = "radix") => 11,
23 if cfg!(feature = "radix") => 11,
24 if cfg!(feature = "radix") => 11,
25 if cfg!(feature = "radix") => 11,
26 if cfg!(feature = "radix") => 11,
27 if cfg!(feature = "radix") => 11,
28 if cfg!(feature = "radix") => 11,
29 if cfg!(feature = "radix") => 10,
30 if cfg!(feature = "radix") => 10,
31 if cfg!(feature = "radix") => 10,
32 if cfg!(feature = "power-of-two") => 10,
33 if cfg!(feature = "radix") => 10,
34 if cfg!(feature = "radix") => 10,
35 if cfg!(feature = "radix") => 10,
36 if cfg!(feature = "radix") => 10,
_ => 0,
}
}
#[inline(always)]
pub const fn u32_power_limit(radix: u32) -> u32 {
match radix {
2 if cfg!(feature = "power-of-two") => 31,
3 if cfg!(feature = "radix") => 20,
4 if cfg!(feature = "power-of-two") => 15,
5 => 13,
6 if cfg!(feature = "radix") => 12,
7 if cfg!(feature = "radix") => 11,
8 if cfg!(feature = "power-of-two") => 10,
9 if cfg!(feature = "radix") => 10,
10 => 9,
11 if cfg!(feature = "radix") => 9,
12 if cfg!(feature = "radix") => 8,
13 if cfg!(feature = "radix") => 8,
14 if cfg!(feature = "radix") => 8,
15 if cfg!(feature = "radix") => 8,
16 if cfg!(feature = "power-of-two") => 7,
17 if cfg!(feature = "radix") => 7,
18 if cfg!(feature = "radix") => 7,
19 if cfg!(feature = "radix") => 7,
20 if cfg!(feature = "radix") => 7,
21 if cfg!(feature = "radix") => 7,
22 if cfg!(feature = "radix") => 7,
23 if cfg!(feature = "radix") => 7,
24 if cfg!(feature = "radix") => 6,
25 if cfg!(feature = "radix") => 6,
26 if cfg!(feature = "radix") => 6,
27 if cfg!(feature = "radix") => 6,
28 if cfg!(feature = "radix") => 6,
29 if cfg!(feature = "radix") => 6,
30 if cfg!(feature = "radix") => 6,
31 if cfg!(feature = "radix") => 6,
32 if cfg!(feature = "power-of-two") => 6,
33 if cfg!(feature = "radix") => 6,
34 if cfg!(feature = "radix") => 6,
35 if cfg!(feature = "radix") => 6,
36 if cfg!(feature = "radix") => 6,
_ => 1,
}
}
#[inline(always)]
pub const fn u64_power_limit(radix: u32) -> u32 {
match radix {
2 if cfg!(feature = "power-of-two") => 63,
3 if cfg!(feature = "radix") => 40,
4 if cfg!(feature = "power-of-two") => 31,
5 => 27,
6 if cfg!(feature = "radix") => 24,
7 if cfg!(feature = "radix") => 22,
8 if cfg!(feature = "power-of-two") => 21,
9 if cfg!(feature = "radix") => 20,
10 => 19,
11 if cfg!(feature = "radix") => 18,
12 if cfg!(feature = "radix") => 17,
13 if cfg!(feature = "radix") => 17,
14 if cfg!(feature = "radix") => 16,
15 if cfg!(feature = "radix") => 16,
16 if cfg!(feature = "power-of-two") => 15,
17 if cfg!(feature = "radix") => 15,
18 if cfg!(feature = "radix") => 15,
19 if cfg!(feature = "radix") => 15,
20 if cfg!(feature = "radix") => 14,
21 if cfg!(feature = "radix") => 14,
22 if cfg!(feature = "radix") => 14,
23 if cfg!(feature = "radix") => 14,
24 if cfg!(feature = "radix") => 13,
25 if cfg!(feature = "radix") => 13,
26 if cfg!(feature = "radix") => 13,
27 if cfg!(feature = "radix") => 13,
28 if cfg!(feature = "radix") => 13,
29 if cfg!(feature = "radix") => 13,
30 if cfg!(feature = "radix") => 13,
31 if cfg!(feature = "radix") => 12,
32 if cfg!(feature = "power-of-two") => 12,
33 if cfg!(feature = "radix") => 12,
34 if cfg!(feature = "radix") => 12,
35 if cfg!(feature = "radix") => 12,
36 if cfg!(feature = "radix") => 12,
_ => 1,
}
}
pub trait MaxDigits {
fn max_digits(radix: u32) -> Option<usize>;
}
impl MaxDigits for f32 {
#[inline(always)]
fn max_digits(radix: u32) -> Option<usize> {
debug_assert_radix(radix);
f32_max_digits(radix)
}
}
impl MaxDigits for f64 {
#[inline(always)]
fn max_digits(radix: u32) -> Option<usize> {
debug_assert_radix(radix);
f64_max_digits(radix)
}
}
#[cfg(feature = "f16")]
impl MaxDigits for f16 {
#[inline(always)]
fn max_digits(_: u32) -> Option<usize> {
unimplemented!()
}
}
#[cfg(feature = "f16")]
impl MaxDigits for bf16 {
#[inline(always)]
fn max_digits(_: u32) -> Option<usize> {
unimplemented!()
}
}
#[inline(always)]
pub const fn f32_max_digits(radix: u32) -> Option<usize> {
match radix {
6 => Some(103),
10 => Some(114),
12 => Some(117),
14 => Some(119),
18 => Some(122),
20 => Some(123),
22 => Some(123),
24 => Some(124),
26 => Some(125),
28 => Some(125),
30 => Some(126),
34 => Some(127),
36 => Some(127),
_ => None,
}
}
#[inline(always)]
pub const fn f64_max_digits(radix: u32) -> Option<usize> {
match radix {
6 => Some(682),
10 => Some(769),
12 => Some(792),
14 => Some(808),
18 => Some(832),
20 => Some(840),
22 => Some(848),
24 => Some(854),
26 => Some(859),
28 => Some(864),
30 => Some(868),
34 => Some(876),
36 => Some(879),
_ => None,
}
}