@@ -1134,6 +1134,14 @@ TEST_CASE("double.inf") {
11341134 std::errc::result_out_of_range);
11351135 verify (" 1.9e308" , std::numeric_limits<double >::infinity (),
11361136 std::errc::result_out_of_range);
1137+
1138+ // DBL_MAX + 0.00000000000000001e308
1139+ verify (" 1.79769313486231581e308" , std::numeric_limits<double >::infinity (),
1140+ std::errc::result_out_of_range);
1141+
1142+ // DBL_MAX + 0.0000000000000001e308
1143+ verify (" 1.7976931348623159e308" , std::numeric_limits<double >::infinity (),
1144+ std::errc::result_out_of_range);
11371145}
11381146
11391147TEST_CASE (" double.general" ) {
@@ -1143,6 +1151,13 @@ TEST_CASE("double.general") {
11431151 verify (" -22250738585072012e-324" ,
11441152 -0x1p-1022 ); /* limit between normal and subnormal*/
11451153 verify (" -1e-999" , -0.0 , std::errc::result_out_of_range);
1154+
1155+ // DBL_TRUE_MIN / 2
1156+ verify (" 2.4703282292062327e-324" , 0.0 , std::errc::result_out_of_range);
1157+
1158+ // DBL_TRUE_MIN / 2 + 0.0000000000000001e-324
1159+ verify (" 2.4703282292062328e-324" , 0x0 .0000000000001p-1022 );
1160+
11461161 verify (" -2.2222222222223e-322" , -0x1 .68p-1069 );
11471162 verify (" 9007199254740993.0" , 0x1p+53 );
11481163 verify (" 860228122.6654514319E+90" , 0x1 .92bb20990715fp+328 );
@@ -2070,3 +2085,114 @@ TEST_CASE("bfloat16.general") {
20702085 // 0.00000000000000000000000000000000000001175494210692441075487029444849287348827052428745893333857174530571588870475618904265502351336181163787841796875bf16);
20712086}
20722087#endif
2088+
2089+ template <typename Int>
2090+ void integer_multiplication_by_power_of_10_test (Int mantissa,
2091+ int decimal_exponent,
2092+ double expected) {
2093+ const double actual =
2094+ fast_float::multiply_integer_and_power_of_10 (mantissa, decimal_exponent);
2095+
2096+ INFO (" m * 10^e=" << mantissa << " * 10^" << decimal_exponent
2097+ << " \n "
2098+ " expected="
2099+ << fHexAndDec (expected) << " \n "
2100+ << " ..actual=" << fHexAndDec (actual) << " \n "
2101+ << " expected mantissa="
2102+ << iHexAndDec (get_mantissa (expected)) << " \n "
2103+ << " ..actual mantissa=" << iHexAndDec (get_mantissa (actual))
2104+ << " \n " );
2105+ CHECK_EQ (actual, expected);
2106+ }
2107+
2108+ #define verify_integer_multiplication_by_power_of_10 (mantissa, \
2109+ decimal_exponent) \
2110+ do { \
2111+ integer_multiplication_by_power_of_10_test (mantissa, decimal_exponent, \
2112+ mantissa##e##decimal_exponent); \
2113+ } while (false )
2114+
2115+ TEST_CASE (" multiply_integer_and_power_of_10" ) {
2116+ // explicitly verifying API with different types of integers
2117+ integer_multiplication_by_power_of_10_test<char >(31 , -1 , 3.1 );
2118+ integer_multiplication_by_power_of_10_test<unsigned char >(31 , -1 , 3.1 );
2119+ integer_multiplication_by_power_of_10_test<signed char >(31 , -1 , 3.1 );
2120+ integer_multiplication_by_power_of_10_test<signed char >(-31 , -1 , -3.1 );
2121+ integer_multiplication_by_power_of_10_test<int16_t >(31415 , -4 , 3.1415 );
2122+ integer_multiplication_by_power_of_10_test<int16_t >(-31415 , -4 , -3.1415 );
2123+ integer_multiplication_by_power_of_10_test<uint16_t >(31415 , -4 , 3.1415 );
2124+ integer_multiplication_by_power_of_10_test<int32_t >(314159265 , -8 ,
2125+ 3.14159265 );
2126+ integer_multiplication_by_power_of_10_test<int32_t >(-314159265 , -8 ,
2127+ -3.14159265 );
2128+ integer_multiplication_by_power_of_10_test<uint32_t >(3141592653 , -9 ,
2129+ 3.141592653 );
2130+ integer_multiplication_by_power_of_10_test<int64_t >(3141592653589793238 , -18 ,
2131+ 3.141592653589793238 );
2132+ integer_multiplication_by_power_of_10_test<int64_t >(-3141592653589793238 , -18 ,
2133+ -3.141592653589793238 );
2134+ integer_multiplication_by_power_of_10_test<uint64_t >(3141592653589793238 , -18 ,
2135+ 3.141592653589793238 );
2136+
2137+ for (int mode : {FE_UPWARD, FE_DOWNWARD, FE_TOWARDZERO, FE_TONEAREST}) {
2138+ fesetround (mode);
2139+ INFO (" fesetround(): " << std::string{round_name (mode)});
2140+
2141+ struct Guard {
2142+ ~Guard () { fesetround (FE_TONEAREST); }
2143+ } guard;
2144+
2145+ verify_integer_multiplication_by_power_of_10 (0 , 0 );
2146+ verify_integer_multiplication_by_power_of_10 (1 , 0 );
2147+ verify_integer_multiplication_by_power_of_10 (0 , 1 );
2148+ verify_integer_multiplication_by_power_of_10 (1 , 1 );
2149+ verify_integer_multiplication_by_power_of_10 (-1 , 0 );
2150+ verify_integer_multiplication_by_power_of_10 (0 , -1 );
2151+ verify_integer_multiplication_by_power_of_10 (-1 , -1 );
2152+ verify_integer_multiplication_by_power_of_10 (-1 , 1 );
2153+ verify_integer_multiplication_by_power_of_10 (1 , -1 );
2154+ verify_integer_multiplication_by_power_of_10 (-1 , -1 );
2155+
2156+ integer_multiplication_by_power_of_10_test (49406564584124654 , -340 ,
2157+ DBL_TRUE_MIN);
2158+ integer_multiplication_by_power_of_10_test (22250738585072014 , -324 ,
2159+ DBL_MIN);
2160+ integer_multiplication_by_power_of_10_test (17976931348623158 , 292 , DBL_MAX);
2161+
2162+ // DBL_TRUE_MIN / 2 underflows to 0
2163+ integer_multiplication_by_power_of_10_test (49406564584124654 / 2 , -340 , 0 .);
2164+
2165+ // DBL_TRUE_MIN / 2 + 0.0000000000000001e-324 rounds to DBL_TRUE_MIN
2166+ integer_multiplication_by_power_of_10_test (49406564584124654 / 2 + 1 , -340 ,
2167+ DBL_TRUE_MIN);
2168+
2169+ // DBL_MAX + 0.0000000000000001e308 overflows to infinity
2170+ integer_multiplication_by_power_of_10_test (
2171+ 17976931348623158 + 1 , 292 , std::numeric_limits<double >::infinity ());
2172+
2173+ // loosely verifying correct rounding of 1 to 64 bits
2174+ // worth of significant digits
2175+ verify_integer_multiplication_by_power_of_10 (1 , 42 );
2176+ verify_integer_multiplication_by_power_of_10 (12 , 42 );
2177+ verify_integer_multiplication_by_power_of_10 (123 , 42 );
2178+ verify_integer_multiplication_by_power_of_10 (1234 , 42 );
2179+ verify_integer_multiplication_by_power_of_10 (12345 , 42 );
2180+ verify_integer_multiplication_by_power_of_10 (123456 , 42 );
2181+ verify_integer_multiplication_by_power_of_10 (1234567 , 42 );
2182+ verify_integer_multiplication_by_power_of_10 (12345678 , 42 );
2183+ verify_integer_multiplication_by_power_of_10 (123456789 , 42 );
2184+ verify_integer_multiplication_by_power_of_10 (1234567890 , 42 );
2185+ verify_integer_multiplication_by_power_of_10 (12345678901 , 42 );
2186+ verify_integer_multiplication_by_power_of_10 (123456789012 , 42 );
2187+ verify_integer_multiplication_by_power_of_10 (1234567890123 , 42 );
2188+ verify_integer_multiplication_by_power_of_10 (12345678901234 , 42 );
2189+ verify_integer_multiplication_by_power_of_10 (123456789012345 , 42 );
2190+ verify_integer_multiplication_by_power_of_10 (1234567890123456 , 42 );
2191+ verify_integer_multiplication_by_power_of_10 (12345678901234567 , 42 );
2192+ verify_integer_multiplication_by_power_of_10 (123456789012345678 , 42 );
2193+ verify_integer_multiplication_by_power_of_10 (1234567890123456789 , 42 );
2194+ verify_integer_multiplication_by_power_of_10 (12345678901234567890 , 42 );
2195+ // ULLONG_MAX
2196+ verify_integer_multiplication_by_power_of_10 (18446744073709551615 , 42 );
2197+ }
2198+ }
0 commit comments