Skip to content

Commit 069c26a

Browse files
authored
Merge pull request #796 from cppalliance/limits
Fix limits and printing of subnormal_min
2 parents 394daf2 + 4ae8c77 commit 069c26a

18 files changed

+252
-81
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Dd00000000001000000000000000000000000000000000001000000000ccccccccc�Cccc0ccccccccc8888000010000)001.2

fuzzing/old_crashes/fuzz_snprintf/crash-da39a3ee5e6b4b0d3255bfef95601890afd80709

Whitespace-only changes.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
0000000000000000000000000000000000000000

include/boost/decimal/charconv.hpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -353,7 +353,7 @@ BOOST_DECIMAL_CONSTEXPR auto to_chars_scientific_impl(char* first, char* last, c
353353
}
354354

355355
const auto fp = fpclassify(value);
356-
if (fp != FP_NORMAL)
356+
if (!(fp == FP_NORMAL || fp == FP_SUBNORMAL))
357357
{
358358
return to_chars_nonfinite(first, last, value, fp, fmt, precision);
359359
}
@@ -494,7 +494,7 @@ BOOST_DECIMAL_CONSTEXPR auto to_chars_fixed_impl(char* first, char* last, const
494494
}
495495

496496
const auto fp = fpclassify(value);
497-
if (fp != FP_NORMAL)
497+
if (!(fp == FP_NORMAL || fp == FP_SUBNORMAL))
498498
{
499499
return to_chars_nonfinite(first, last, value, fp, fmt, precision);
500500
}
@@ -720,7 +720,7 @@ BOOST_DECIMAL_CONSTEXPR auto to_chars_hex_impl(char* first, char* last, const Ta
720720
}
721721

722722
const auto fp = fpclassify(value);
723-
if (fp != FP_NORMAL)
723+
if (!(fp == FP_NORMAL || fp == FP_SUBNORMAL))
724724
{
725725
return to_chars_nonfinite(first, last, value, fp, chars_format::hex, precision);
726726
}
@@ -742,7 +742,7 @@ BOOST_DECIMAL_CONSTEXPR auto to_chars_hex_impl(char* first, char* last, const Ta
742742
Unsigned_Integer significand = frexp10(value, &exp);
743743
BOOST_DECIMAL_ASSERT(significand != 0);
744744
// Strip zeros of the significand since frexp10 normalizes it
745-
while (significand % 10U == 0)
745+
while (significand % 10U == 0 && significand > 0)
746746
{
747747
significand /= 10U;
748748
++exp;

include/boost/decimal/decimal128.hpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2238,18 +2238,18 @@ struct numeric_limits<boost::decimal::decimal128>
22382238
static constexpr int digits10 = digits;
22392239
static constexpr int max_digits10 = digits;
22402240
static constexpr int radix = 10;
2241-
static constexpr int min_exponent = -6142;
2241+
static constexpr int min_exponent = -6143;
22422242
static constexpr int min_exponent10 = min_exponent;
2243-
static constexpr int max_exponent = 6145;
2243+
static constexpr int max_exponent = 6144;
22442244
static constexpr int max_exponent10 = max_exponent;
22452245
static constexpr bool traps = numeric_limits<std::uint64_t>::traps;
22462246
static constexpr bool tinyness_before = true;
22472247

22482248
// Member functions
22492249
static constexpr auto (min) () -> boost::decimal::decimal128 { return {1, min_exponent}; }
2250-
static constexpr auto (max) () -> boost::decimal::decimal128 { return {boost::decimal::detail::uint128{UINT64_C(999'999'999'999'999), UINT64_C(9'999'999'999'999'999'999)}, max_exponent}; }
2251-
static constexpr auto lowest () -> boost::decimal::decimal128 { return {boost::decimal::detail::uint128{UINT64_C(999'999'999'999'999), UINT64_C(9'999'999'999'999'999'999)}, max_exponent, true}; }
2252-
static constexpr auto epsilon () -> boost::decimal::decimal128 { return {1, -34}; }
2250+
static constexpr auto (max) () -> boost::decimal::decimal128 { return {boost::decimal::detail::uint128{UINT64_C(0b1111011010000100110111110101011011000011111000000), UINT64_C(0b0011011110001101100011100110001111111111111111111111111111111111)}, max_exponent - digits + 1}; }
2251+
static constexpr auto lowest () -> boost::decimal::decimal128 { return {boost::decimal::detail::uint128{UINT64_C(0b1111011010000100110111110101011011000011111000000), UINT64_C(0b0011011110001101100011100110001111111111111111111111111111111111)}, max_exponent - digits + 1, true}; }
2252+
static constexpr auto epsilon () -> boost::decimal::decimal128 { return {1, -digits + 1}; }
22532253
static constexpr auto round_error () -> boost::decimal::decimal128 { return epsilon(); }
22542254
static constexpr auto infinity () -> boost::decimal::decimal128 { return boost::decimal::from_bits(boost::decimal::detail::d128_inf_mask); }
22552255
static constexpr auto quiet_NaN () -> boost::decimal::decimal128 { return boost::decimal::from_bits(boost::decimal::detail::d128_nan_mask); }

include/boost/decimal/decimal128_fast.hpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1484,25 +1484,25 @@ struct numeric_limits<boost::decimal::decimal128_fast>
14841484
static constexpr int digits10 = digits;
14851485
static constexpr int max_digits10 = digits;
14861486
static constexpr int radix = 10;
1487-
static constexpr int min_exponent = -6142;
1487+
static constexpr int min_exponent = -6143;
14881488
static constexpr int min_exponent10 = min_exponent;
1489-
static constexpr int max_exponent = 6145;
1489+
static constexpr int max_exponent = 6144;
14901490
static constexpr int max_exponent10 = max_exponent;
14911491
static constexpr bool traps = numeric_limits<std::uint64_t>::traps;
14921492
static constexpr bool tinyness_before = true;
14931493

14941494
// Member functions
14951495
static constexpr auto (min) () -> boost::decimal::decimal128_fast { return {1, min_exponent}; }
1496-
static constexpr auto (max) () -> boost::decimal::decimal128_fast { return {boost::decimal::detail::uint128{UINT64_C(999'999'999'999'999), UINT64_C(9'999'999'999'999'999'999)}, max_exponent}; }
1497-
static constexpr auto lowest () -> boost::decimal::decimal128_fast { return {boost::decimal::detail::uint128{UINT64_C(999'999'999'999'999), UINT64_C(9'999'999'999'999'999'999)}, max_exponent, true}; }
1498-
static constexpr auto epsilon () -> boost::decimal::decimal128_fast { return {1, -34}; }
1496+
static constexpr auto (max) () -> boost::decimal::decimal128_fast { return {boost::decimal::detail::uint128{UINT64_C(0b1111011010000100110111110101011011000011111000000), UINT64_C(0b0011011110001101100011100110001111111111111111111111111111111111)}, max_exponent - digits + 1}; }
1497+
static constexpr auto lowest () -> boost::decimal::decimal128_fast { return {boost::decimal::detail::uint128{UINT64_C(0b1111011010000100110111110101011011000011111000000), UINT64_C(0b0011011110001101100011100110001111111111111111111111111111111111)}, max_exponent - digits + 1, true}; }
1498+
static constexpr auto epsilon () -> boost::decimal::decimal128_fast { return {1, -digits + 1}; }
14991499
static constexpr auto round_error () -> boost::decimal::decimal128_fast { return epsilon(); }
15001500
static constexpr auto infinity () -> boost::decimal::decimal128_fast { return boost::decimal::direct_init_d128(boost::decimal::detail::d128_fast_inf, 0, false); }
15011501
static constexpr auto quiet_NaN () -> boost::decimal::decimal128_fast { return boost::decimal::direct_init_d128(boost::decimal::detail::d128_fast_qnan, 0, false); }
15021502
static constexpr auto signaling_NaN() -> boost::decimal::decimal128_fast { return boost::decimal::direct_init_d128(boost::decimal::detail::d128_fast_snan, 0, false); }
1503-
static constexpr auto denorm_min () -> boost::decimal::decimal128_fast { return {1, boost::decimal::detail::etiny_v<boost::decimal::decimal128>}; }
1503+
static constexpr auto denorm_min () -> boost::decimal::decimal128_fast { return min(); }
15041504
};
15051505

1506-
}
1506+
} // namspace std
15071507

15081508
#endif //BOOST_DECIMAL_DECIMAL128_FAST_HPP

include/boost/decimal/decimal32.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2248,9 +2248,9 @@ struct numeric_limits<boost::decimal::decimal32>
22482248

22492249
// Member functions
22502250
static constexpr auto (min) () -> boost::decimal::decimal32 { return {1, min_exponent}; }
2251-
static constexpr auto (max) () -> boost::decimal::decimal32 { return {9'999'999, max_exponent}; }
2252-
static constexpr auto lowest () -> boost::decimal::decimal32 { return {-9'999'999, max_exponent}; }
2253-
static constexpr auto epsilon () -> boost::decimal::decimal32 { return {1, -7}; }
2251+
static constexpr auto (max) () -> boost::decimal::decimal32 { return {9'999'999, max_exponent - digits + 1}; }
2252+
static constexpr auto lowest () -> boost::decimal::decimal32 { return {9'999'999, max_exponent - digits + 1, true}; }
2253+
static constexpr auto epsilon () -> boost::decimal::decimal32 { return {1, -digits + 1}; }
22542254
static constexpr auto round_error () -> boost::decimal::decimal32 { return epsilon(); }
22552255
static constexpr auto infinity () -> boost::decimal::decimal32 { return boost::decimal::from_bits(boost::decimal::detail::d32_inf_mask); }
22562256
static constexpr auto quiet_NaN () -> boost::decimal::decimal32 { return boost::decimal::from_bits(boost::decimal::detail::d32_nan_mask); }

include/boost/decimal/decimal32_fast.hpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1481,16 +1481,16 @@ struct numeric_limits<boost::decimal::decimal32_fast>
14811481

14821482
// Member functions
14831483
static constexpr auto (min) () -> boost::decimal::decimal32_fast { return {1, min_exponent}; }
1484-
static constexpr auto (max) () -> boost::decimal::decimal32_fast { return {9'999'999, max_exponent}; }
1485-
static constexpr auto lowest () -> boost::decimal::decimal32_fast { return {-9'999'999, max_exponent}; }
1486-
static constexpr auto epsilon () -> boost::decimal::decimal32_fast { return {1, -7}; }
1484+
static constexpr auto (max) () -> boost::decimal::decimal32_fast { return {9'999'999, max_exponent - digits + 1}; }
1485+
static constexpr auto lowest () -> boost::decimal::decimal32_fast { return {9'999'999, max_exponent - digits + 1, true}; }
1486+
static constexpr auto epsilon () -> boost::decimal::decimal32_fast { return {1, -digits + 1}; }
14871487
static constexpr auto round_error () -> boost::decimal::decimal32_fast { return epsilon(); }
14881488
static constexpr auto infinity () -> boost::decimal::decimal32_fast { return boost::decimal::direct_init(boost::decimal::detail::d32_fast_inf, UINT8_C((0))); }
14891489
static constexpr auto quiet_NaN () -> boost::decimal::decimal32_fast { return boost::decimal::direct_init(boost::decimal::detail::d32_fast_qnan, UINT8_C((0))); }
14901490
static constexpr auto signaling_NaN() -> boost::decimal::decimal32_fast { return boost::decimal::direct_init(boost::decimal::detail::d32_fast_snan, UINT8_C((0))); }
14911491

14921492
// With denorm absent returns the same value as min
1493-
static constexpr auto denorm_min () -> boost::decimal::decimal32_fast { return {1, min_exponent}; }
1493+
static constexpr auto denorm_min () -> boost::decimal::decimal32_fast { return min(); }
14941494
};
14951495

14961496
} // Namespace std

include/boost/decimal/decimal64.hpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2149,18 +2149,18 @@ struct numeric_limits<boost::decimal::decimal64>
21492149
static constexpr int digits10 = digits;
21502150
static constexpr int max_digits10 = digits;
21512151
static constexpr int radix = 10;
2152-
static constexpr int min_exponent = -382;
2152+
static constexpr int min_exponent = -383;
21532153
static constexpr int min_exponent10 = min_exponent;
2154-
static constexpr int max_exponent = 385;
2154+
static constexpr int max_exponent = 384;
21552155
static constexpr int max_exponent10 = max_exponent;
21562156
static constexpr bool traps = numeric_limits<std::uint64_t>::traps;
21572157
static constexpr bool tinyness_before = true;
21582158

21592159
// Member functions
21602160
static constexpr auto (min) () -> boost::decimal::decimal64 { return {1, min_exponent}; }
2161-
static constexpr auto (max) () -> boost::decimal::decimal64 { return {9'999'999'999'999'999, max_exponent}; }
2162-
static constexpr auto lowest () -> boost::decimal::decimal64 { return {-9'999'999'999'999'999, max_exponent}; }
2163-
static constexpr auto epsilon () -> boost::decimal::decimal64 { return {1, -16}; }
2161+
static constexpr auto (max) () -> boost::decimal::decimal64 { return {9'999'999'999'999'999, max_exponent - digits + 1}; }
2162+
static constexpr auto lowest () -> boost::decimal::decimal64 { return {9'999'999'999'999'999, max_exponent - digits + 1, true}; }
2163+
static constexpr auto epsilon () -> boost::decimal::decimal64 { return {1, -digits + 1}; }
21642164
static constexpr auto round_error () -> boost::decimal::decimal64 { return epsilon(); }
21652165
static constexpr auto infinity () -> boost::decimal::decimal64 { return boost::decimal::from_bits(boost::decimal::detail::d64_inf_mask); }
21662166
static constexpr auto quiet_NaN () -> boost::decimal::decimal64 { return boost::decimal::from_bits(boost::decimal::detail::d64_nan_mask); }

include/boost/decimal/decimal64_fast.hpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1427,26 +1427,26 @@ struct numeric_limits<boost::decimal::decimal64_fast>
14271427
static constexpr int digits10 = digits;
14281428
static constexpr int max_digits10 = digits;
14291429
static constexpr int radix = 10;
1430-
static constexpr int min_exponent = -382;
1430+
static constexpr int min_exponent = -383;
14311431
static constexpr int min_exponent10 = min_exponent;
1432-
static constexpr int max_exponent = 385;
1432+
static constexpr int max_exponent = 384;
14331433
static constexpr int max_exponent10 = max_exponent;
14341434
static constexpr bool traps = numeric_limits<std::uint_fast64_t>::traps;
14351435
static constexpr bool tinyness_before = true;
14361436

14371437
// Member functions
14381438
static constexpr auto (min) () -> boost::decimal::decimal64_fast { return {1, min_exponent}; }
1439-
static constexpr auto (max) () -> boost::decimal::decimal64_fast { return {9'999'999'999'999'999, max_exponent}; }
1440-
static constexpr auto lowest () -> boost::decimal::decimal64_fast { return {-9'999'999'999'999'999, max_exponent}; }
1441-
static constexpr auto epsilon () -> boost::decimal::decimal64_fast { return {1, -16}; }
1439+
static constexpr auto (max) () -> boost::decimal::decimal64_fast { return {9'999'999'999'999'999, max_exponent - digits + 1}; }
1440+
static constexpr auto lowest () -> boost::decimal::decimal64_fast { return {9'999'999'999'999'999, max_exponent - digits + 1, true}; }
1441+
static constexpr auto epsilon () -> boost::decimal::decimal64_fast { return {1, -digits + 1}; }
14421442
static constexpr auto round_error () -> boost::decimal::decimal64_fast { return epsilon(); }
14431443
static constexpr auto infinity () -> boost::decimal::decimal64_fast { return boost::decimal::direct_init_d64(
14441444
boost::decimal::detail::d64_fast_inf, 0, false); }
14451445
static constexpr auto quiet_NaN () -> boost::decimal::decimal64_fast { return boost::decimal::direct_init_d64(
14461446
boost::decimal::detail::d64_fast_qnan, 0, false); }
14471447
static constexpr auto signaling_NaN() -> boost::decimal::decimal64_fast { return boost::decimal::direct_init_d64(
14481448
boost::decimal::detail::d64_fast_snan, 0, false); }
1449-
static constexpr auto denorm_min () -> boost::decimal::decimal64_fast { return {1, boost::decimal::detail::etiny_v<boost::decimal::decimal64>}; }
1449+
static constexpr auto denorm_min () -> boost::decimal::decimal64_fast { return min(); }
14501450
};
14511451

14521452
} // namespace std

0 commit comments

Comments
 (0)