@@ -1153,6 +1153,99 @@ TEST_CASE("double.inf") {
11531153 std::errc::result_out_of_range);
11541154}
11551155
1156+ TEST_CASE (" truncated integer mantissa" ) {
1157+ constexpr size_t max_digits = fast_float::binary_format<double >::max_digits ();
1158+ constexpr size_t integer_digits = max_digits + 1 ;
1159+ constexpr size_t fraction_length = 1024 ;
1160+
1161+ auto make_mantissa = [=](char final_integer_digit,
1162+ char final_fraction_digit) {
1163+ std::string input = " 1234567890123456789" ;
1164+ input.append (integer_digits - input.size () - 1 , ' 0' );
1165+ input.push_back (final_integer_digit);
1166+ input.push_back (' .' );
1167+ input.append (fraction_length - 1 , ' 0' );
1168+ input.push_back (final_fraction_digit);
1169+ return input;
1170+ };
1171+
1172+ auto parse_mantissa = [=](std::string const &input,
1173+ fast_float::bigint &result) -> size_t {
1174+ fast_float::parse_options options;
1175+ auto number = fast_float::parse_number_string<false >(
1176+ input.data (), input.data () + input.size (), options, true );
1177+ CHECK (number.valid );
1178+ CHECK (number.integer .len () == integer_digits);
1179+ CHECK (number.fraction .len () == fraction_length);
1180+
1181+ size_t digits = 0 ;
1182+ fast_float::parse_mantissa (result, number, max_digits, digits);
1183+ return digits;
1184+ };
1185+
1186+ auto const nonzero_integer_zero_fraction = make_mantissa (' 1' , ' 0' );
1187+ auto const nonzero_integer_nonzero_fraction = make_mantissa (' 1' , ' 1' );
1188+ fast_float::bigint nonzero_integer_zero_result;
1189+ fast_float::bigint nonzero_integer_nonzero_result;
1190+ CHECK (parse_mantissa (nonzero_integer_zero_fraction,
1191+ nonzero_integer_zero_result) == max_digits + 1 );
1192+ CHECK (parse_mantissa (nonzero_integer_nonzero_fraction,
1193+ nonzero_integer_nonzero_result) == max_digits + 1 );
1194+ CHECK (nonzero_integer_zero_result.compare (nonzero_integer_nonzero_result) ==
1195+ 0 );
1196+
1197+ auto const zero_integer_zero_fraction = make_mantissa (' 0' , ' 0' );
1198+ auto const zero_integer_nonzero_fraction = make_mantissa (' 0' , ' 1' );
1199+ fast_float::bigint zero_integer_zero_result;
1200+ fast_float::bigint zero_integer_nonzero_result;
1201+ CHECK (parse_mantissa (zero_integer_zero_fraction, zero_integer_zero_result) ==
1202+ max_digits);
1203+ CHECK (parse_mantissa (zero_integer_nonzero_fraction,
1204+ zero_integer_nonzero_result) == max_digits + 1 );
1205+ CHECK (zero_integer_zero_result.compare (zero_integer_nonzero_result) < 0 );
1206+
1207+ auto make_exact_conversion_input = [=](char final_fraction_digit) {
1208+ std::string input = " 8385788696668661046" ;
1209+ input.append (integer_digits - input.size () - 1 , ' 0' );
1210+ input.push_back (' 1' );
1211+ input.push_back (' .' );
1212+ input.append (fraction_length - 1 , ' 0' );
1213+ input.push_back (final_fraction_digit);
1214+ input += " e-1078" ;
1215+ return input;
1216+ };
1217+
1218+ auto const exact_input = make_exact_conversion_input (' 0' );
1219+ fast_float::parse_options options;
1220+ auto const number = fast_float::parse_number_string<false >(
1221+ exact_input.data (), exact_input.data () + exact_input.size (), options,
1222+ true );
1223+ REQUIRE (number.too_many_digits );
1224+ REQUIRE (number.integer .len () == integer_digits);
1225+ REQUIRE (number.fraction .len () == fraction_length);
1226+ auto const approximate =
1227+ fast_float::compute_float<fast_float::binary_format<double >>(
1228+ number.exponent , number.mantissa );
1229+ auto const next =
1230+ fast_float::compute_float<fast_float::binary_format<double >>(
1231+ number.exponent , number.mantissa + 1 );
1232+ REQUIRE (approximate != next);
1233+ REQUIRE (fast_float::compute_error<fast_float::binary_format<double >>(
1234+ number.exponent , number.mantissa )
1235+ .power2 < 0 );
1236+
1237+ for (char final_fraction_digit = ' 0' ; final_fraction_digit <= ' 1' ;
1238+ ++final_fraction_digit) {
1239+ auto const input = make_exact_conversion_input (final_fraction_digit);
1240+ double value = 0 ;
1241+ auto const result = fast_float::from_chars (
1242+ input.data (), input.data () + input.size (), value);
1243+ CHECK (result.ec == std::errc ());
1244+ CHECK (result.ptr == input.data () + input.size ());
1245+ CHECK (value == 0x0 .607b00a417628p-1022 );
1246+ }
1247+ }
1248+
11561249TEST_CASE (" double.general" ) {
11571250 verify (" 0.95000000000000000000" , 0.95 );
11581251 verify (" 22250738585072012e-324" ,
0 commit comments