#![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!()
}
}
#[must_use]
#[inline(always)]
#[cfg(feature = "radix")]
pub const fn f32_exponent_limit(radix: u32) -> (i64, i64) {
match radix {
2 => (-127, 127),
3 => (-15, 15),
4 => (-63, 63),
5 => (-10, 10),
6 => (-15, 15),
7 => (-8, 8),
8 => (-42, 42),
9 => (-7, 7),
10 => (-10, 10),
11 => (-6, 6),
12 => (-15, 15),
13 => (-6, 6),
14 => (-8, 8),
15 => (-6, 6),
16 => (-31, 31),
17 => (-5, 5),
18 => (-7, 7),
19 => (-5, 5),
20 => (-10, 10),
21 => (-5, 5),
22 => (-6, 6),
23 => (-5, 5),
24 => (-15, 15),
25 => (-5, 5),
26 => (-6, 6),
27 => (-5, 5),
28 => (-8, 8),
29 => (-4, 4),
30 => (-6, 6),
31 => (-4, 4),
32 => (-25, 25),
33 => (-4, 4),
34 => (-5, 5),
35 => (-4, 4),
36 => (-7, 7),
_ => (0, 0),
}
}
#[must_use]
#[inline(always)]
#[cfg(all(feature = "power-of-two", not(feature = "radix")))]
pub const fn f32_exponent_limit(radix: u32) -> (i64, i64) {
match radix {
2 => (-127, 127),
4 => (-63, 63),
8 => (-42, 42),
10 => (-10, 10),
16 => (-31, 31),
32 => (-25, 25),
_ => (0, 0),
}
}
#[must_use]
#[inline(always)]
#[cfg(not(feature = "power-of-two"))]
pub const fn f32_exponent_limit(radix: u32) -> (i64, i64) {
match radix {
10 => (-10, 10),
_ => (0, 0),
}
}
#[must_use]
#[inline(always)]
#[cfg(feature = "radix")]
pub const fn f32_mantissa_limit(radix: u32) -> i64 {
match radix {
2 => 24,
3 => 15,
4 => 12,
5 => 10,
6 => 9,
7 => 8,
8 => 8,
9 => 7,
10 => 7,
11 => 6,
12 => 6,
13 => 6,
14 => 6,
15 => 6,
16 => 6,
17 => 5,
18 => 5,
19 => 5,
20 => 5,
21 => 5,
22 => 5,
23 => 5,
24 => 5,
25 => 5,
26 => 5,
27 => 5,
28 => 4,
29 => 4,
30 => 4,
31 => 4,
32 => 4,
33 => 4,
34 => 4,
35 => 4,
36 => 4,
_ => 0,
}
}
#[must_use]
#[inline(always)]
#[cfg(all(feature = "power-of-two", not(feature = "radix")))]
pub const fn f32_mantissa_limit(radix: u32) -> i64 {
match radix {
2 => 24,
4 => 12,
8 => 8,
10 => 7,
16 => 6,
32 => 4,
_ => 0,
}
}
#[must_use]
#[inline(always)]
#[cfg(not(feature = "power-of-two"))]
pub const fn f32_mantissa_limit(radix: u32) -> i64 {
match radix {
10 => 7,
_ => 0,
}
}
#[must_use]
#[inline(always)]
#[cfg(feature = "radix")]
pub const fn f64_exponent_limit(radix: u32) -> (i64, i64) {
match radix {
2 => (-1023, 1023),
3 => (-33, 33),
4 => (-511, 511),
5 => (-22, 22),
6 => (-33, 33),
7 => (-18, 18),
8 => (-341, 341),
9 => (-16, 16),
10 => (-22, 22),
11 => (-15, 15),
12 => (-33, 33),
13 => (-14, 14),
14 => (-18, 18),
15 => (-13, 13),
16 => (-255, 255),
17 => (-12, 12),
18 => (-16, 16),
19 => (-12, 12),
20 => (-22, 22),
21 => (-12, 12),
22 => (-15, 15),
23 => (-11, 11),
24 => (-33, 33),
25 => (-11, 11),
26 => (-14, 14),
27 => (-11, 11),
28 => (-18, 18),
29 => (-10, 10),
30 => (-13, 13),
31 => (-10, 10),
32 => (-204, 204),
33 => (-10, 10),
34 => (-12, 12),
35 => (-10, 10),
36 => (-16, 16),
_ => (0, 0),
}
}
#[must_use]
#[inline(always)]
#[cfg(all(feature = "power-of-two", not(feature = "radix")))]
pub const fn f64_exponent_limit(radix: u32) -> (i64, i64) {
match radix {
2 => (-1023, 1023),
4 => (-511, 511),
8 => (-341, 341),
10 => (-22, 22),
16 => (-255, 255),
32 => (-204, 204),
_ => (0, 0),
}
}
#[must_use]
#[inline(always)]
#[cfg(not(feature = "power-of-two"))]
pub const fn f64_exponent_limit(radix: u32) -> (i64, i64) {
match radix {
10 => (-22, 22),
_ => (0, 0),
}
}
#[must_use]
#[inline(always)]
#[cfg(feature = "radix")]
pub const fn f64_mantissa_limit(radix: u32) -> i64 {
match radix {
2 => 53,
3 => 33,
4 => 26,
5 => 22,
6 => 20,
7 => 18,
8 => 17,
9 => 16,
10 => 15,
11 => 15,
12 => 14,
13 => 14,
14 => 13,
15 => 13,
16 => 13,
17 => 12,
18 => 12,
19 => 12,
20 => 12,
21 => 12,
22 => 11,
23 => 11,
24 => 11,
25 => 11,
26 => 11,
27 => 11,
28 => 11,
29 => 10,
30 => 10,
31 => 10,
32 => 10,
33 => 10,
34 => 10,
35 => 10,
36 => 10,
_ => 0,
}
}
#[must_use]
#[inline(always)]
#[cfg(all(feature = "power-of-two", not(feature = "radix")))]
pub const fn f64_mantissa_limit(radix: u32) -> i64 {
match radix {
2 => 53,
4 => 26,
8 => 17,
10 => 15,
16 => 13,
32 => 10,
_ => 0,
}
}
#[must_use]
#[inline(always)]
#[cfg(not(feature = "power-of-two"))]
pub const fn f64_mantissa_limit(radix: u32) -> i64 {
match radix {
10 => 15,
_ => 0,
}
}
#[must_use]
#[inline(always)]
#[cfg(feature = "f128")]
#[cfg(feature = "radix")]
pub const fn f128_exponent_limit(radix: u32) -> (i64, i64) {
match radix {
2 => (-16494, 16383),
3 => (-71, 71),
4 => (-8247, 8191),
5 => (-48, 48),
6 => (-71, 71),
7 => (-40, 40),
8 => (-5498, 5461),
9 => (-35, 35),
10 => (-48, 48),
11 => (-32, 32),
12 => (-71, 71),
13 => (-30, 30),
14 => (-40, 40),
15 => (-28, 28),
16 => (-4123, 4095),
17 => (-27, 27),
18 => (-35, 35),
19 => (-26, 26),
20 => (-48, 48),
21 => (-25, 25),
22 => (-32, 32),
23 => (-24, 24),
24 => (-71, 71),
25 => (-24, 24),
26 => (-30, 30),
27 => (-23, 23),
28 => (-40, 40),
29 => (-23, 23),
30 => (-28, 28),
31 => (-22, 22),
32 => (-3298, 3276),
33 => (-22, 22),
34 => (-27, 27),
35 => (-22, 22),
36 => (-35, 35),
_ => (0, 0),
}
}
#[inline(always)]
#[cfg(feature = "f128")]
#[cfg(all(feature = "power-of-two", not(feature = "radix")))]
pub const fn f128_exponent_limit(radix: u32) -> (i64, i64) {
match radix {
2 => (-16494, 16383),
4 => (-8247, 8191),
8 => (-5498, 5461),
10 => (-48, 48),
16 => (-4123, 4095),
32 => (-3298, 3276),
_ => (0, 0),
}
}
#[must_use]
#[inline(always)]
#[cfg(feature = "f128")]
#[cfg(not(feature = "power-of-two"))]
pub const fn f128_exponent_limit(radix: u32) -> (i64, i64) {
match radix {
10 => (-48, 48),
_ => (0, 0),
}
}
#[must_use]
#[inline(always)]
#[cfg(feature = "f128")]
#[cfg(feature = "radix")]
pub const fn f128_mantissa_limit(radix: u32) -> i64 {
match radix {
2 => 113,
3 => 71,
4 => 56,
5 => 48,
6 => 43,
7 => 40,
8 => 37,
9 => 35,
10 => 34,
11 => 32,
12 => 31,
13 => 30,
14 => 29,
15 => 28,
16 => 28,
17 => 27,
18 => 27,
19 => 26,
20 => 26,
21 => 25,
22 => 25,
23 => 24,
24 => 24,
25 => 24,
26 => 24,
27 => 23,
28 => 23,
29 => 23,
30 => 23,
31 => 22,
32 => 22,
33 => 22,
34 => 22,
35 => 22,
36 => 21,
_ => 0,
}
}
#[must_use]
#[inline(always)]
#[cfg(feature = "f128")]
#[cfg(all(feature = "power-of-two", not(feature = "radix")))]
pub const fn f128_mantissa_limit(radix: u32) -> i64 {
match radix {
2 => 113,
4 => 56,
8 => 37,
10 => 34,
16 => 28,
32 => 22,
_ => 0,
}
}
#[must_use]
#[inline(always)]
#[cfg(feature = "f128")]
#[cfg(not(feature = "power-of-two"))]
pub const fn f128_mantissa_limit(radix: u32) -> i64 {
match radix {
10 => 34,
_ => 0,
}
}
#[must_use]
#[inline(always)]
#[cfg(feature = "radix")]
pub const fn u32_power_limit(radix: u32) -> u32 {
match radix {
2 => 31,
3 => 20,
4 => 15,
5 => 13,
6 => 12,
7 => 11,
8 => 10,
9 => 10,
10 => 9,
11 => 9,
12 => 8,
13 => 8,
14 => 8,
15 => 8,
16 => 7,
17 => 7,
18 => 7,
19 => 7,
20 => 7,
21 => 7,
22 => 7,
23 => 7,
24 => 6,
25 => 6,
26 => 6,
27 => 6,
28 => 6,
29 => 6,
30 => 6,
31 => 6,
32 => 6,
33 => 6,
34 => 6,
35 => 6,
36 => 6,
_ => 1,
}
}
#[must_use]
#[inline(always)]
#[cfg(all(feature = "power-of-two", not(feature = "radix")))]
pub const fn u32_power_limit(radix: u32) -> u32 {
match radix {
2 => 31,
4 => 15,
5 => 13,
8 => 10,
10 => 9,
16 => 7,
32 => 6,
_ => 1,
}
}
#[must_use]
#[inline(always)]
#[cfg(not(feature = "power-of-two"))]
pub const fn u32_power_limit(radix: u32) -> u32 {
match radix {
5 => 13,
10 => 9,
_ => 1,
}
}
#[must_use]
#[inline(always)]
#[cfg(feature = "radix")]
pub const fn u64_power_limit(radix: u32) -> u32 {
match radix {
2 => 63,
3 => 40,
4 => 31,
5 => 27,
6 => 24,
7 => 22,
8 => 21,
9 => 20,
10 => 19,
11 => 18,
12 => 17,
13 => 17,
14 => 16,
15 => 16,
16 => 15,
17 => 15,
18 => 15,
19 => 15,
20 => 14,
21 => 14,
22 => 14,
23 => 14,
24 => 13,
25 => 13,
26 => 13,
27 => 13,
28 => 13,
29 => 13,
30 => 13,
31 => 12,
32 => 12,
33 => 12,
34 => 12,
35 => 12,
36 => 12,
_ => 1,
}
}
#[must_use]
#[inline(always)]
#[cfg(all(feature = "power-of-two", not(feature = "radix")))]
pub const fn u64_power_limit(radix: u32) -> u32 {
match radix {
2 => 63,
4 => 31,
5 => 27,
8 => 21,
10 => 19,
16 => 15,
32 => 12,
_ => 1,
}
}
#[must_use]
#[inline(always)]
#[cfg(not(feature = "power-of-two"))]
pub const fn u64_power_limit(radix: u32) -> u32 {
match radix {
5 => 27,
10 => 19,
_ => 1,
}
}
#[allow(clippy::doc_markdown)] 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!()
}
}
#[must_use]
#[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,
}
}
#[must_use]
#[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,
}
}