@@ -1161,6 +1161,8 @@ class cpp_double_fp_backend
11611161template <typename FloatingPointType>
11621162constexpr auto cpp_double_fp_backend<FloatingPointType>::rd_string(const char * p_str) -> bool
11631163{
1164+ // Use an intermediate cpp_bin_float backend type for reading string input.
1165+
11641166 cpp_bin_float_read_write_backend_type f_bin { };
11651167
11661168 f_bin = p_str;
@@ -1197,96 +1199,107 @@ constexpr auto cpp_double_fp_backend<FloatingPointType>::rd_string(const char* p
11971199 }()
11981200 };
11991201
1200- using cpp_bin_float_read_write_exp_type = typename cpp_bin_float_read_write_backend_type::exponent_type;
1201-
12021202 const auto is_zero_or_subnormal =
12031203 (
12041204 (fpc == FP_ZERO)
1205- || (expval_from_f_bin < static_cast <cpp_bin_float_read_write_exp_type >(local_double_fp_type::my_min_exponent))
1205+ || (expval_from_f_bin < static_cast <typename cpp_bin_float_read_write_backend_type::exponent_type >(local_double_fp_type::my_min_exponent))
12061206 );
12071207
12081208 if (is_zero_or_subnormal)
12091209 {
12101210 data.first = float_type { 0 .0F };
12111211 data.second = float_type { 0 .0F };
1212+
1213+ return true ;
12121214 }
1213- else
1214- {
1215- bool is_definitely_inf { (fpc == FP_INFINITE) };
12161215
1217- if (!is_definitely_inf)
1218- {
1219- float_type flt_inf_check { };
1216+ float_type flt_inf_check_first { };
12201217
1221- eval_convert_to (&flt_inf_check , f_bin);
1218+ eval_convert_to (&flt_inf_check_first , f_bin);
12221219
1223- if (flt_inf_check > my_value_max ().my_first ())
1224- {
1225- is_definitely_inf = true ;
1226- }
1227- };
1220+ bool is_definitely_inf { ((fpc == FP_INFINITE) || cpp_df_qf_detail::ccmath::isinf (flt_inf_check_first)) };
12281221
1229- if (is_definitely_inf)
1222+ if (!is_definitely_inf)
1223+ {
1224+ if (flt_inf_check_first > my_value_max ().my_first ())
12301225 {
1231- static_cast <void >(operator =(local_double_fp_type::my_value_inf ()));
1226+ cpp_bin_float_read_write_backend_type f_bin_inf_check (f_bin);
1227+
1228+ eval_subtract (f_bin_inf_check, cpp_bin_float_read_write_backend_type (flt_inf_check_first));
1229+
1230+ float_type flt_inf_check_second { };
1231+
1232+ eval_convert_to (&flt_inf_check_second, f_bin_inf_check);
12321233
1233- if (b_neg) { negate (); }
1234+ is_definitely_inf = eval_gt ( local_double_fp_type (flt_inf_check_first, flt_inf_check_second), my_value_max ());
12341235 }
1235- else
1236+ };
1237+
1238+ if (is_definitely_inf)
1239+ {
1240+ static_cast <void >(operator =(local_double_fp_type::my_value_inf ()));
1241+
1242+ if (b_neg)
12361243 {
1237- data. first = float_type { 0 . 0F } ;
1238- data. second = float_type { 0 . 0F };
1244+ negate () ;
1245+ }
12391246
1240- constexpr int pow2_scaling_for_small_input { cpp_df_qf_detail::ccmath::numeric_limits<float_type>::digits };
1247+ return true ;
1248+ }
12411249
1242- const auto has_pow2_scaling_for_small_input =
1243- (
1244- expval_from_f_bin < static_cast <int >(local_double_fp_type::my_min_exponent + pow2_scaling_for_small_input)
1245- );
1250+ // The input string is normal. We will now extract its value.
12461251
1247- if (has_pow2_scaling_for_small_input)
1248- {
1249- eval_ldexp (f_bin, f_bin, pow2_scaling_for_small_input);
1250- }
1252+ data.first = float_type { 0 .0F };
1253+ data.second = float_type { 0 .0F };
12511254
1252- using local_builtin_float_type = typename std::conditional<( sizeof ( float_type) <= sizeof ( double )), double , float_type >::type ;
1255+ constexpr int pow2_scaling_for_small_input { cpp_df_qf_detail::ccmath::numeric_limits< float_type>::digits } ;
12531256
1254- constexpr unsigned
1255- digit_limit
1256- {
1257- static_cast <unsigned >
1258- (
1259- static_cast <int >
1260- (
1261- (local_double_fp_type::my_digits / cpp_df_qf_detail::ccmath::numeric_limits<local_builtin_float_type>::digits)
1262- + (((local_double_fp_type::my_digits % cpp_df_qf_detail::ccmath::numeric_limits<local_builtin_float_type>::digits) != 0 ) ? 1 : 0 )
1263- )
1264- * cpp_df_qf_detail::ccmath::numeric_limits<local_builtin_float_type>::digits
1265- )
1266- };
1257+ const auto has_pow2_scaling_for_small_input =
1258+ (
1259+ expval_from_f_bin < static_cast <int >(local_double_fp_type::my_min_exponent + pow2_scaling_for_small_input)
1260+ );
12671261
1268- for (auto i = static_cast <unsigned >(UINT8_C (0 ));
1269- i < digit_limit;
1270- i = static_cast <unsigned >(i + static_cast <unsigned >(cpp_df_qf_detail::ccmath::numeric_limits<local_builtin_float_type>::digits)))
1271- {
1272- local_builtin_float_type flt_part { };
1262+ if (has_pow2_scaling_for_small_input)
1263+ {
1264+ eval_ldexp (f_bin, f_bin, pow2_scaling_for_small_input);
1265+ }
1266+
1267+ using local_builtin_float_type = typename std::conditional<(sizeof (float_type) <= sizeof (double )), double , float_type>::type;
1268+
1269+ constexpr unsigned
1270+ digit_limit
1271+ {
1272+ static_cast <unsigned >
1273+ (
1274+ static_cast <int >
1275+ (
1276+ (local_double_fp_type::my_digits / cpp_df_qf_detail::ccmath::numeric_limits<local_builtin_float_type>::digits)
1277+ + (((local_double_fp_type::my_digits % cpp_df_qf_detail::ccmath::numeric_limits<local_builtin_float_type>::digits) != 0 ) ? 1 : 0 )
1278+ )
1279+ * cpp_df_qf_detail::ccmath::numeric_limits<local_builtin_float_type>::digits
1280+ )
1281+ };
12731282
1274- eval_convert_to (&flt_part, f_bin);
1283+ for (auto i = static_cast <unsigned >(UINT8_C (0 ));
1284+ i < digit_limit;
1285+ i = static_cast <unsigned >(i + static_cast <unsigned >(cpp_df_qf_detail::ccmath::numeric_limits<local_builtin_float_type>::digits)))
1286+ {
1287+ local_builtin_float_type flt_part { };
12751288
1276- eval_subtract (f_bin, cpp_bin_float_read_write_backend_type (flt_part) );
1289+ eval_convert_to (&flt_part, f_bin );
12771290
1278- eval_add (*this , local_double_fp_type { flt_part });
1279- }
1291+ eval_subtract (f_bin, cpp_bin_float_read_write_backend_type (flt_part));
12801292
1281- if (has_pow2_scaling_for_small_input)
1282- {
1283- eval_ldexp (*this , *this , -pow2_scaling_for_small_input);
1284- }
1293+ eval_add (*this , local_double_fp_type { flt_part });
1294+ }
12851295
1286- if (b_neg) { negate (); }
1287- }
1296+ if (has_pow2_scaling_for_small_input)
1297+ {
1298+ eval_ldexp (*this , *this , -pow2_scaling_for_small_input);
12881299 }
12891300
1301+ if (b_neg) { negate (); }
1302+
12901303 return true ;
12911304}
12921305
0 commit comments