3333
3434namespace fast_float {
3535
36+ // 64 bit integer is used because mantissa can be up to 53 bits for double.
37+ // Value of the int mantissa in the API.
38+ typedef int_fast64_t am_sign_mant_t ;
39+ // An unsigned int avoids signed overflows (which are bad)
40+ typedef uint_fast64_t am_mant_t ;
41+
3642// The number of digits in the mantissa.
3743typedef uint_fast16_t am_digits;
3844
3945// The number of bits in the limb.
4046typedef uint_fast8_t limb_t ;
4147
48+ // Size of bits in the mantissa and path and rounding shifts
49+ typedef int_fast8_t am_bits_t ;
50+
51+ // 16 bit signed integer is used for power to cover all double exponents.
52+ typedef int16_t am_pow_t ;
53+ // Power bias is signed for handling a denormal float
54+ // or an invalid mantissa.
55+ // Bias so we can get the real exponent with an invalid adjusted_mantissa.
56+ constexpr static am_pow_t invalid_am_bias =
57+ std::numeric_limits<am_pow_t >::min() + 1 ;
58+ constexpr static am_pow_t am_bias_limit =
59+ (std::numeric_limits<am_pow_t >::max() / 8 ) - 1 ;
60+
4261// Type for enum chars_format.
4362typedef uint_fast8_t chars_format_t ;
4463
@@ -355,8 +374,11 @@ struct alignas(16) value128 {
355374};
356375
357376/* Helper C++14 constexpr generic implementation of leading_zeroes for 64-bit */
358- fastfloat_really_inline FASTFLOAT_CONSTEXPR14 am_digits
359- leading_zeroes_generic (uint64_t input_num, uint32_t last_bit = 0 ) noexcept {
377+ fastfloat_really_inline FASTFLOAT_CONSTEXPR14 limb_t
378+ leading_zeroes_generic (uint64_t input_num) noexcept {
379+ assert (input_num > 0 );
380+ FASTFLOAT_ASSUME (input_num > 0 );
381+ uint_fast32_t last_bit = 0 ;
360382 if (input_num & uint64_t (0xffffffff00000000 )) {
361383 input_num >>= 32 ;
362384 last_bit |= 32 ;
@@ -380,11 +402,11 @@ leading_zeroes_generic(uint64_t input_num, uint32_t last_bit = 0) noexcept {
380402 if (input_num & uint64_t (0x2 )) { /* input_num >>= 1; */
381403 last_bit |= 1 ;
382404 }
383- return 63 - static_cast <am_digits >(last_bit);
405+ return 63 - static_cast <limb_t >(last_bit);
384406}
385407
386408/* result might be undefined when input_num is zero */
387- fastfloat_really_inline FASTFLOAT_CONSTEXPR20 am_digits
409+ fastfloat_really_inline FASTFLOAT_CONSTEXPR20 limb_t
388410leading_zeroes (uint64_t input_num) noexcept {
389411 assert (input_num > 0 );
390412 FASTFLOAT_ASSUME (input_num > 0 );
@@ -397,21 +419,20 @@ leading_zeroes(uint64_t input_num) noexcept {
397419 // Search the mask data from most significant bit (MSB)
398420 // to least significant bit (LSB) for a set bit (1).
399421 _BitScanReverse64 (&leading_zero, input_num);
400- return static_cast <am_digits >(63 - leading_zero);
422+ return static_cast <limb_t >(63 - leading_zero);
401423#else
402- return static_cast <am_digits >(leading_zeroes_generic (input_num));
424+ return static_cast <limb_t >(leading_zeroes_generic (input_num));
403425#endif
404426#else
405- return static_cast <am_digits >(__builtin_clzll (input_num));
427+ return static_cast <limb_t >(__builtin_clzll (input_num));
406428#endif
407429}
408430
409431/* Helper C++14 constexpr generic implementation of countr_zero for 32-bit */
410- fastfloat_really_inline FASTFLOAT_CONSTEXPR14 am_digits
432+ fastfloat_really_inline FASTFLOAT_CONSTEXPR14 limb_t
411433countr_zero_generic_32 (uint32_t input_num) {
412- if (input_num == 0 ) {
413- return 32 ;
414- }
434+ assert (input_num > 0 );
435+ FASTFLOAT_ASSUME (input_num > 0 );
415436 uint_fast16_t last_bit = 0 ;
416437 if (!(input_num & 0x0000FFFF )) {
417438 input_num >>= 16 ;
@@ -432,23 +453,23 @@ countr_zero_generic_32(uint32_t input_num) {
432453 if (!(input_num & 0x1 )) {
433454 last_bit |= 1 ;
434455 }
435- return static_cast <am_digits >(last_bit);
456+ return static_cast <limb_t >(last_bit);
436457}
437458
438459/* count trailing zeroes for 32-bit integers */
439- fastfloat_really_inline FASTFLOAT_CONSTEXPR20 am_digits
460+ fastfloat_really_inline FASTFLOAT_CONSTEXPR20 limb_t
440461countr_zero_32 (uint32_t input_num) {
441462 if (cpp20_and_in_constexpr ()) {
442463 return countr_zero_generic_32 (input_num);
443464 }
444465#ifdef FASTFLOAT_VISUAL_STUDIO
445466 unsigned long trailing_zero = 0 ;
446467 if (_BitScanForward (&trailing_zero, input_num)) {
447- return static_cast <am_digits >(trailing_zero);
468+ return static_cast <limb_t >(trailing_zero);
448469 }
449470 return 32 ;
450471#else
451- return input_num == 0 ? 32 : static_cast <am_digits >(__builtin_ctz (input_num));
472+ return input_num == 0 ? 32 : static_cast <limb_t >(__builtin_ctz (input_num));
452473#endif
453474}
454475
@@ -509,25 +530,6 @@ full_multiplication(uint64_t a, uint64_t b) noexcept {
509530 return answer;
510531}
511532
512- // 64 bit integer is used because mantissa can be up to 53 bits for double.
513- // Value of the int mantissa in the API.
514- typedef int_fast64_t am_sign_mant_t ;
515- // An unsigned int avoids signed overflows (which are bad)
516- typedef uint_fast64_t am_mant_t ;
517-
518- // Size of bits in the mantissa and path and rounding shifts
519- typedef int_fast8_t am_bits_t ;
520-
521- // 16 bit signed integer is used for power to cover all double exponents.
522- // Power bias is signed for handling a denormal float
523- // or an invalid mantissa.
524- typedef int_fast16_t am_pow_t ;
525- // Bias so we can get the real exponent with an invalid adjusted_mantissa.
526- constexpr static am_pow_t invalid_am_bias =
527- std::numeric_limits<int16_t >::min() + 1 ;
528- constexpr static am_pow_t am_bias_limit =
529- (std::numeric_limits<int16_t >::max() + 1 ) / 8 ;
530-
531533struct alignas (16 ) adjusted_mantissa {
532534 am_mant_t mantissa;
533535 am_pow_t power2;
@@ -550,21 +552,21 @@ template <typename T, typename U = void> struct binary_format_lookup_tables;
550552template <typename T> struct binary_format : binary_format_lookup_tables<T> {
551553 using equiv_uint = equiv_uint_t <T>;
552554
553- static constexpr limb_t mantissa_explicit_bits ();
555+ static constexpr am_bits_t mantissa_explicit_bits ();
554556 static constexpr am_pow_t minimum_exponent ();
555557 static constexpr am_pow_t infinite_power ();
556558 static constexpr am_bits_t sign_index ();
557559 static constexpr am_bits_t
558560 min_exponent_fast_path (); // used when fegetround() == FE_TONEAREST
559561 static constexpr am_bits_t max_exponent_fast_path ();
560- static constexpr am_bits_t max_exponent_round_to_even ();
561- static constexpr am_bits_t min_exponent_round_to_even ();
562- static constexpr equiv_uint max_mantissa_fast_path (am_pow_t power);
562+ static constexpr am_pow_t max_exponent_round_to_even ();
563+ static constexpr am_pow_t min_exponent_round_to_even ();
564+ static constexpr equiv_uint max_mantissa_fast_path (am_pow_t const power);
563565 static constexpr equiv_uint
564566 max_mantissa_fast_path (); // used when fegetround() == FE_TONEAREST
565567 static constexpr am_pow_t largest_power_of_ten ();
566568 static constexpr am_pow_t smallest_power_of_ten ();
567- static constexpr T exact_power_of_ten (am_pow_t power);
569+ static constexpr T exact_power_of_ten (am_pow_t const power);
568570 static constexpr am_digits max_digits ();
569571 static constexpr equiv_uint exponent_mask ();
570572 static constexpr equiv_uint mantissa_mask ();
@@ -673,32 +675,32 @@ inline constexpr am_bits_t binary_format<float>::min_exponent_fast_path() {
673675}
674676
675677template <>
676- inline constexpr limb_t binary_format<double >::mantissa_explicit_bits() {
678+ inline constexpr am_bits_t binary_format<double >::mantissa_explicit_bits() {
677679 return 52 ;
678680}
679681
680682template <>
681- inline constexpr limb_t binary_format<float >::mantissa_explicit_bits() {
683+ inline constexpr am_bits_t binary_format<float >::mantissa_explicit_bits() {
682684 return 23 ;
683685}
684686
685687template <>
686- inline constexpr am_bits_t binary_format<double >::max_exponent_round_to_even() {
688+ inline constexpr am_pow_t binary_format<double >::max_exponent_round_to_even() {
687689 return 23 ;
688690}
689691
690692template <>
691- inline constexpr am_bits_t binary_format<float >::max_exponent_round_to_even() {
693+ inline constexpr am_pow_t binary_format<float >::max_exponent_round_to_even() {
692694 return 10 ;
693695}
694696
695697template <>
696- inline constexpr am_bits_t binary_format<double >::min_exponent_round_to_even() {
698+ inline constexpr am_pow_t binary_format<double >::min_exponent_round_to_even() {
697699 return -4 ;
698700}
699701
700702template <>
701- inline constexpr am_bits_t binary_format<float >::min_exponent_round_to_even() {
703+ inline constexpr am_pow_t binary_format<float >::min_exponent_round_to_even() {
702704 return -17 ;
703705}
704706
@@ -807,7 +809,7 @@ binary_format<std::float16_t>::max_exponent_fast_path() {
807809}
808810
809811template <>
810- inline constexpr limb_t
812+ inline constexpr am_bits_t
811813binary_format<std::float16_t >::mantissa_explicit_bits() {
812814 return 10 ;
813815}
@@ -829,13 +831,13 @@ binary_format<std::float16_t>::min_exponent_fast_path() {
829831}
830832
831833template <>
832- inline constexpr am_bits_t
834+ inline constexpr am_pow_t
833835binary_format<std::float16_t >::max_exponent_round_to_even() {
834836 return 5 ;
835837}
836838
837839template <>
838- inline constexpr am_bits_t
840+ inline constexpr am_pow_t
839841binary_format<std::float16_t >::min_exponent_round_to_even() {
840842 return -22 ;
841843}
@@ -934,7 +936,7 @@ binary_format<std::bfloat16_t>::hidden_bit_mask() {
934936}
935937
936938template <>
937- inline constexpr limb_t
939+ inline constexpr am_bits_t
938940binary_format<std::bfloat16_t >::mantissa_explicit_bits() {
939941 return 7 ;
940942}
@@ -956,13 +958,13 @@ binary_format<std::bfloat16_t>::min_exponent_fast_path() {
956958}
957959
958960template <>
959- inline constexpr am_bits_t
961+ inline constexpr am_pow_t
960962binary_format<std::bfloat16_t >::max_exponent_round_to_even() {
961963 return 3 ;
962964}
963965
964966template <>
965- inline constexpr am_bits_t
967+ inline constexpr am_pow_t
966968binary_format<std::bfloat16_t >::min_exponent_round_to_even() {
967969 return -24 ;
968970}
0 commit comments