1#![doc(hidden)]
4
5use lexical_util::assert::debug_assert_radix;
6#[cfg(feature = "f16")]
7use lexical_util::bf16::bf16;
8#[cfg(feature = "f16")]
9use lexical_util::f16::f16;
10
11#[doc(hidden)]
37pub trait ExactFloat {
38 fn exponent_limit(radix: u32) -> (i64, i64);
40
41 fn mantissa_limit(radix: u32) -> i64;
43}
44
45impl ExactFloat for f32 {
46 #[inline(always)]
47 fn exponent_limit(radix: u32) -> (i64, i64) {
48 debug_assert_radix(radix);
49 f32_exponent_limit(radix)
50 }
51
52 #[inline(always)]
53 fn mantissa_limit(radix: u32) -> i64 {
54 debug_assert_radix(radix);
55 f32_mantissa_limit(radix)
56 }
57}
58
59impl ExactFloat for f64 {
60 #[inline(always)]
61 fn exponent_limit(radix: u32) -> (i64, i64) {
62 debug_assert_radix(radix);
63 f64_exponent_limit(radix)
64 }
65
66 #[inline(always)]
67 fn mantissa_limit(radix: u32) -> i64 {
68 debug_assert_radix(radix);
69 f64_mantissa_limit(radix)
70 }
71}
72
73#[cfg(feature = "f16")]
74impl ExactFloat for f16 {
75 #[inline(always)]
76 fn exponent_limit(_: u32) -> (i64, i64) {
77 unimplemented!()
78 }
79
80 #[inline(always)]
81 fn mantissa_limit(_: u32) -> i64 {
82 unimplemented!()
83 }
84}
85
86#[cfg(feature = "f16")]
87impl ExactFloat for bf16 {
88 #[inline(always)]
89 fn exponent_limit(_: u32) -> (i64, i64) {
90 unimplemented!()
91 }
92
93 #[inline(always)]
94 fn mantissa_limit(_: u32) -> i64 {
95 unimplemented!()
96 }
97}
98
99#[must_use]
120#[inline(always)]
121#[cfg(feature = "radix")]
122pub const fn f32_exponent_limit(radix: u32) -> (i64, i64) {
123 match radix {
124 2 => (-127, 127),
125 3 => (-15, 15),
126 4 => (-63, 63),
127 5 => (-10, 10),
128 6 => (-15, 15),
129 7 => (-8, 8),
130 8 => (-42, 42),
131 9 => (-7, 7),
132 10 => (-10, 10),
133 11 => (-6, 6),
134 12 => (-15, 15),
135 13 => (-6, 6),
136 14 => (-8, 8),
137 15 => (-6, 6),
138 16 => (-31, 31),
139 17 => (-5, 5),
140 18 => (-7, 7),
141 19 => (-5, 5),
142 20 => (-10, 10),
143 21 => (-5, 5),
144 22 => (-6, 6),
145 23 => (-5, 5),
146 24 => (-15, 15),
147 25 => (-5, 5),
148 26 => (-6, 6),
149 27 => (-5, 5),
150 28 => (-8, 8),
151 29 => (-4, 4),
152 30 => (-6, 6),
153 31 => (-4, 4),
154 32 => (-25, 25),
155 33 => (-4, 4),
156 34 => (-5, 5),
157 35 => (-4, 4),
158 36 => (-7, 7),
159 _ => (0, 0),
160 }
161}
162
163#[must_use]
165#[inline(always)]
166#[cfg(all(feature = "power-of-two", not(feature = "radix")))]
167pub const fn f32_exponent_limit(radix: u32) -> (i64, i64) {
168 match radix {
169 2 => (-127, 127),
170 4 => (-63, 63),
171 8 => (-42, 42),
172 10 => (-10, 10),
173 16 => (-31, 31),
174 32 => (-25, 25),
175 _ => (0, 0),
176 }
177}
178
179#[must_use]
181#[inline(always)]
182#[cfg(not(feature = "power-of-two"))]
183pub const fn f32_exponent_limit(radix: u32) -> (i64, i64) {
184 match radix {
185 10 => (-10, 10),
186 _ => (0, 0),
187 }
188}
189
190#[must_use]
192#[inline(always)]
193#[cfg(feature = "radix")]
194pub const fn f32_mantissa_limit(radix: u32) -> i64 {
195 match radix {
196 2 => 24,
197 3 => 15,
198 4 => 12,
199 5 => 10,
200 6 => 9,
201 7 => 8,
202 8 => 8,
203 9 => 7,
204 10 => 7,
205 11 => 6,
206 12 => 6,
207 13 => 6,
208 14 => 6,
209 15 => 6,
210 16 => 6,
211 17 => 5,
212 18 => 5,
213 19 => 5,
214 20 => 5,
215 21 => 5,
216 22 => 5,
217 23 => 5,
218 24 => 5,
219 25 => 5,
220 26 => 5,
221 27 => 5,
222 28 => 4,
223 29 => 4,
224 30 => 4,
225 31 => 4,
226 32 => 4,
227 33 => 4,
228 34 => 4,
229 35 => 4,
230 36 => 4,
231 _ => 0,
232 }
233}
234
235#[must_use]
237#[inline(always)]
238#[cfg(all(feature = "power-of-two", not(feature = "radix")))]
239pub const fn f32_mantissa_limit(radix: u32) -> i64 {
240 match radix {
241 2 => 24,
242 4 => 12,
243 8 => 8,
244 10 => 7,
245 16 => 6,
246 32 => 4,
247 _ => 0,
248 }
249}
250
251#[must_use]
253#[inline(always)]
254#[cfg(not(feature = "power-of-two"))]
255pub const fn f32_mantissa_limit(radix: u32) -> i64 {
256 match radix {
257 10 => 7,
258 _ => 0,
259 }
260}
261
262#[must_use]
264#[inline(always)]
265#[cfg(feature = "radix")]
266pub const fn f64_exponent_limit(radix: u32) -> (i64, i64) {
267 match radix {
268 2 => (-1023, 1023),
269 3 => (-33, 33),
270 4 => (-511, 511),
271 5 => (-22, 22),
272 6 => (-33, 33),
273 7 => (-18, 18),
274 8 => (-341, 341),
275 9 => (-16, 16),
276 10 => (-22, 22),
277 11 => (-15, 15),
278 12 => (-33, 33),
279 13 => (-14, 14),
280 14 => (-18, 18),
281 15 => (-13, 13),
282 16 => (-255, 255),
283 17 => (-12, 12),
284 18 => (-16, 16),
285 19 => (-12, 12),
286 20 => (-22, 22),
287 21 => (-12, 12),
288 22 => (-15, 15),
289 23 => (-11, 11),
290 24 => (-33, 33),
291 25 => (-11, 11),
292 26 => (-14, 14),
293 27 => (-11, 11),
294 28 => (-18, 18),
295 29 => (-10, 10),
296 30 => (-13, 13),
297 31 => (-10, 10),
298 32 => (-204, 204),
299 33 => (-10, 10),
300 34 => (-12, 12),
301 35 => (-10, 10),
302 36 => (-16, 16),
303 _ => (0, 0),
304 }
305}
306
307#[must_use]
309#[inline(always)]
310#[cfg(all(feature = "power-of-two", not(feature = "radix")))]
311pub const fn f64_exponent_limit(radix: u32) -> (i64, i64) {
312 match radix {
313 2 => (-1023, 1023),
314 4 => (-511, 511),
315 8 => (-341, 341),
316 10 => (-22, 22),
317 16 => (-255, 255),
318 32 => (-204, 204),
319 _ => (0, 0),
320 }
321}
322
323#[must_use]
325#[inline(always)]
326#[cfg(not(feature = "power-of-two"))]
327pub const fn f64_exponent_limit(radix: u32) -> (i64, i64) {
328 match radix {
329 10 => (-22, 22),
330 _ => (0, 0),
331 }
332}
333
334#[must_use]
336#[inline(always)]
337#[cfg(feature = "radix")]
338pub const fn f64_mantissa_limit(radix: u32) -> i64 {
339 match radix {
340 2 => 53,
341 3 => 33,
342 4 => 26,
343 5 => 22,
344 6 => 20,
345 7 => 18,
346 8 => 17,
347 9 => 16,
348 10 => 15,
349 11 => 15,
350 12 => 14,
351 13 => 14,
352 14 => 13,
353 15 => 13,
354 16 => 13,
355 17 => 12,
356 18 => 12,
357 19 => 12,
358 20 => 12,
359 21 => 12,
360 22 => 11,
361 23 => 11,
362 24 => 11,
363 25 => 11,
364 26 => 11,
365 27 => 11,
366 28 => 11,
367 29 => 10,
368 30 => 10,
369 31 => 10,
370 32 => 10,
371 33 => 10,
372 34 => 10,
373 35 => 10,
374 36 => 10,
375 _ => 0,
376 }
377}
378
379#[must_use]
381#[inline(always)]
382#[cfg(all(feature = "power-of-two", not(feature = "radix")))]
383pub const fn f64_mantissa_limit(radix: u32) -> i64 {
384 match radix {
385 2 => 53,
386 4 => 26,
387 8 => 17,
388 10 => 15,
389 16 => 13,
390 32 => 10,
391 _ => 0,
392 }
393}
394
395#[must_use]
397#[inline(always)]
398#[cfg(not(feature = "power-of-two"))]
399pub const fn f64_mantissa_limit(radix: u32) -> i64 {
400 match radix {
401 10 => 15,
402 _ => 0,
403 }
404}
405
406#[must_use]
408#[inline(always)]
409#[cfg(feature = "f128")]
410#[cfg(feature = "radix")]
411pub const fn f128_exponent_limit(radix: u32) -> (i64, i64) {
412 match radix {
413 2 => (-16494, 16383),
414 3 => (-71, 71),
415 4 => (-8247, 8191),
416 5 => (-48, 48),
417 6 => (-71, 71),
418 7 => (-40, 40),
419 8 => (-5498, 5461),
420 9 => (-35, 35),
421 10 => (-48, 48),
422 11 => (-32, 32),
423 12 => (-71, 71),
424 13 => (-30, 30),
425 14 => (-40, 40),
426 15 => (-28, 28),
427 16 => (-4123, 4095),
428 17 => (-27, 27),
429 18 => (-35, 35),
430 19 => (-26, 26),
431 20 => (-48, 48),
432 21 => (-25, 25),
433 22 => (-32, 32),
434 23 => (-24, 24),
435 24 => (-71, 71),
436 25 => (-24, 24),
437 26 => (-30, 30),
438 27 => (-23, 23),
439 28 => (-40, 40),
440 29 => (-23, 23),
441 30 => (-28, 28),
442 31 => (-22, 22),
443 32 => (-3298, 3276),
444 33 => (-22, 22),
445 34 => (-27, 27),
446 35 => (-22, 22),
447 36 => (-35, 35),
448 _ => (0, 0),
450 }
451}
452
453#[inline(always)]
455#[cfg(feature = "f128")]
456#[cfg(all(feature = "power-of-two", not(feature = "radix")))]
457pub const fn f128_exponent_limit(radix: u32) -> (i64, i64) {
458 match radix {
459 2 => (-16494, 16383),
460 4 => (-8247, 8191),
461 8 => (-5498, 5461),
462 10 => (-48, 48),
463 16 => (-4123, 4095),
464 32 => (-3298, 3276),
465 _ => (0, 0),
467 }
468}
469
470#[must_use]
472#[inline(always)]
473#[cfg(feature = "f128")]
474#[cfg(not(feature = "power-of-two"))]
475pub const fn f128_exponent_limit(radix: u32) -> (i64, i64) {
476 match radix {
477 10 => (-48, 48),
478 _ => (0, 0),
480 }
481}
482
483#[must_use]
485#[inline(always)]
486#[cfg(feature = "f128")]
487#[cfg(feature = "radix")]
488pub const fn f128_mantissa_limit(radix: u32) -> i64 {
489 match radix {
490 2 => 113,
491 3 => 71,
492 4 => 56,
493 5 => 48,
494 6 => 43,
495 7 => 40,
496 8 => 37,
497 9 => 35,
498 10 => 34,
499 11 => 32,
500 12 => 31,
501 13 => 30,
502 14 => 29,
503 15 => 28,
504 16 => 28,
505 17 => 27,
506 18 => 27,
507 19 => 26,
508 20 => 26,
509 21 => 25,
510 22 => 25,
511 23 => 24,
512 24 => 24,
513 25 => 24,
514 26 => 24,
515 27 => 23,
516 28 => 23,
517 29 => 23,
518 30 => 23,
519 31 => 22,
520 32 => 22,
521 33 => 22,
522 34 => 22,
523 35 => 22,
524 36 => 21,
525 _ => 0,
527 }
528}
529
530#[must_use]
532#[inline(always)]
533#[cfg(feature = "f128")]
534#[cfg(all(feature = "power-of-two", not(feature = "radix")))]
535pub const fn f128_mantissa_limit(radix: u32) -> i64 {
536 match radix {
537 2 => 113,
538 4 => 56,
539 8 => 37,
540 10 => 34,
541 16 => 28,
542 32 => 22,
543 _ => 0,
545 }
546}
547
548#[must_use]
550#[inline(always)]
551#[cfg(feature = "f128")]
552#[cfg(not(feature = "power-of-two"))]
553pub const fn f128_mantissa_limit(radix: u32) -> i64 {
554 match radix {
555 10 => 34,
556 _ => 0,
558 }
559}
560
561#[must_use]
598#[inline(always)]
599#[cfg(feature = "radix")]
600pub const fn u32_power_limit(radix: u32) -> u32 {
601 match radix {
602 2 => 31,
603 3 => 20,
604 4 => 15,
605 5 => 13,
606 6 => 12,
607 7 => 11,
608 8 => 10,
609 9 => 10,
610 10 => 9,
611 11 => 9,
612 12 => 8,
613 13 => 8,
614 14 => 8,
615 15 => 8,
616 16 => 7,
617 17 => 7,
618 18 => 7,
619 19 => 7,
620 20 => 7,
621 21 => 7,
622 22 => 7,
623 23 => 7,
624 24 => 6,
625 25 => 6,
626 26 => 6,
627 27 => 6,
628 28 => 6,
629 29 => 6,
630 30 => 6,
631 31 => 6,
632 32 => 6,
633 33 => 6,
634 34 => 6,
635 35 => 6,
636 36 => 6,
637 _ => 1,
639 }
640}
641
642#[must_use]
644#[inline(always)]
645#[cfg(all(feature = "power-of-two", not(feature = "radix")))]
646pub const fn u32_power_limit(radix: u32) -> u32 {
647 match radix {
648 2 => 31,
649 4 => 15,
650 5 => 13,
651 8 => 10,
652 10 => 9,
653 16 => 7,
654 32 => 6,
655 _ => 1,
657 }
658}
659
660#[must_use]
662#[inline(always)]
663#[cfg(not(feature = "power-of-two"))]
664pub const fn u32_power_limit(radix: u32) -> u32 {
665 match radix {
666 5 => 13,
667 10 => 9,
668 _ => 1,
670 }
671}
672
673#[must_use]
676#[inline(always)]
677#[cfg(feature = "radix")]
678pub const fn u64_power_limit(radix: u32) -> u32 {
679 match radix {
680 2 => 63,
681 3 => 40,
682 4 => 31,
683 5 => 27,
684 6 => 24,
685 7 => 22,
686 8 => 21,
687 9 => 20,
688 10 => 19,
689 11 => 18,
690 12 => 17,
691 13 => 17,
692 14 => 16,
693 15 => 16,
694 16 => 15,
695 17 => 15,
696 18 => 15,
697 19 => 15,
698 20 => 14,
699 21 => 14,
700 22 => 14,
701 23 => 14,
702 24 => 13,
703 25 => 13,
704 26 => 13,
705 27 => 13,
706 28 => 13,
707 29 => 13,
708 30 => 13,
709 31 => 12,
710 32 => 12,
711 33 => 12,
712 34 => 12,
713 35 => 12,
714 36 => 12,
715 _ => 1,
717 }
718}
719
720#[must_use]
723#[inline(always)]
724#[cfg(all(feature = "power-of-two", not(feature = "radix")))]
725pub const fn u64_power_limit(radix: u32) -> u32 {
726 match radix {
727 2 => 63,
728 4 => 31,
729 5 => 27,
730 8 => 21,
731 10 => 19,
732 16 => 15,
733 32 => 12,
734 _ => 1,
736 }
737}
738
739#[must_use]
740#[inline(always)]
741#[cfg(not(feature = "power-of-two"))]
742pub const fn u64_power_limit(radix: u32) -> u32 {
743 match radix {
744 5 => 27,
745 10 => 19,
746 _ => 1,
748 }
749}
750
751#[allow(clippy::doc_markdown)] pub trait MaxDigits {
864 fn max_digits(radix: u32) -> Option<usize>;
865}
866
867impl MaxDigits for f32 {
870 #[inline(always)]
871 fn max_digits(radix: u32) -> Option<usize> {
872 debug_assert_radix(radix);
873 f32_max_digits(radix)
874 }
875}
876
877impl MaxDigits for f64 {
880 #[inline(always)]
881 fn max_digits(radix: u32) -> Option<usize> {
882 debug_assert_radix(radix);
883 f64_max_digits(radix)
884 }
885}
886
887#[cfg(feature = "f16")]
888impl MaxDigits for f16 {
889 #[inline(always)]
890 fn max_digits(_: u32) -> Option<usize> {
891 unimplemented!()
892 }
893}
894
895#[cfg(feature = "f16")]
896impl MaxDigits for bf16 {
897 #[inline(always)]
898 fn max_digits(_: u32) -> Option<usize> {
899 unimplemented!()
900 }
901}
902
903#[must_use]
935#[inline(always)]
936pub const fn f32_max_digits(radix: u32) -> Option<usize> {
937 match radix {
938 6 => Some(103),
939 10 => Some(114),
940 12 => Some(117),
941 14 => Some(119),
942 18 => Some(122),
943 20 => Some(123),
944 22 => Some(123),
945 24 => Some(124),
946 26 => Some(125),
947 28 => Some(125),
948 30 => Some(126),
949 34 => Some(127),
950 36 => Some(127),
951 _ => None,
954 }
955}
956
957#[must_use]
959#[inline(always)]
960pub const fn f64_max_digits(radix: u32) -> Option<usize> {
961 match radix {
962 6 => Some(682),
963 10 => Some(769),
964 12 => Some(792),
965 14 => Some(808),
966 18 => Some(832),
967 20 => Some(840),
968 22 => Some(848),
969 24 => Some(854),
970 26 => Some(859),
971 28 => Some(864),
972 30 => Some(868),
973 34 => Some(876),
974 36 => Some(879),
975 _ => None,
978 }
979}