diff --git a/libc/src/__support/str_to_float.h b/libc/src/__support/str_to_float.h --- a/libc/src/__support/str_to_float.h +++ b/libc/src/__support/str_to_float.h @@ -1052,13 +1052,12 @@ // If the result is in the valid range, then we use it. The valid range is // also within the int32 range, so this prevents overflow issues. - if (temp_exponent < fputil::FPBits::MAX_EXPONENT && - temp_exponent > -fputil::FPBits::MAX_EXPONENT) { - exponent = static_cast(temp_exponent); - } else if (temp_exponent > fputil::FPBits::MAX_EXPONENT) { + if (temp_exponent > fputil::FPBits::MAX_EXPONENT) { exponent = fputil::FPBits::MAX_EXPONENT; - } else { + } else if (temp_exponent < -fputil::FPBits::MAX_EXPONENT) { exponent = -fputil::FPBits::MAX_EXPONENT; + } else { + exponent = static_cast(temp_exponent); } } } diff --git a/libc/test/src/stdlib/strtod_test.cpp b/libc/test/src/stdlib/strtod_test.cpp --- a/libc/test/src/stdlib/strtod_test.cpp +++ b/libc/test/src/stdlib/strtod_test.cpp @@ -220,6 +220,9 @@ "200000000000000000E608", 1462, uint64_t(0x7ff0000000000000), ERANGE); + // Same as above but for hex. + run_test("0x0164810157p2047", 17, uint64_t(0x7ff0000000000000), ERANGE); + // This bug was in the handling of very large exponents in the exponent // marker. Previously anything greater than 10,000 would be set to 10,000. // This caused incorrect behavior if there were more than 10,000 '0's in the