diff --git a/libc/src/__support/high_precision_decimal.h b/libc/src/__support/high_precision_decimal.h --- a/libc/src/__support/high_precision_decimal.h +++ b/libc/src/__support/high_precision_decimal.h @@ -334,13 +334,24 @@ if ((*numString | 32) == 'e') { ++numString; if (isdigit(*numString) || *numString == '+' || *numString == '-') { - int32_t add_to_exp = strtointeger(numString, 10); - if (add_to_exp > 100000) { - add_to_exp = 100000; - } else if (add_to_exp < -100000) { - add_to_exp = -100000; + auto result = strtointeger(numString, 10); + if (result.has_error()) { + // TODO: handle error } - this->decimal_point += add_to_exp; + int32_t add_to_exponent = result.value; + + // Here we do this operation as int64 to avoid overflow. + int64_t temp_exponent = static_cast(this->decimal_point) + + static_cast(add_to_exponent); + + // Theoretically these numbers should be MAX_EXPONENT for long double, + // but that should be ~16,000 which is much less than 1 << 30. + if (temp_exponent > (1 << 30)) { + temp_exponent = (1 << 30); + } else if (temp_exponent < -(1 << 30)) { + temp_exponent = -(1 << 30); + } + this->decimal_point = static_cast(temp_exponent); } } diff --git a/libc/test/src/__support/high_precision_decimal_test.cpp b/libc/test/src/__support/high_precision_decimal_test.cpp --- a/libc/test/src/__support/high_precision_decimal_test.cpp +++ b/libc/test/src/__support/high_precision_decimal_test.cpp @@ -391,3 +391,18 @@ EXPECT_EQ(hpd.round_to_integer_type(), result); } + +TEST(LlvmLibcHighPrecisionDecimalTest, BigExpTest) { + __llvm_libc::internal::HighPrecisionDecimal big_hpd = + __llvm_libc::internal::HighPrecisionDecimal("1e123456789"); + + // We need to add one to handle the digit before the decimal point in our + // number. + EXPECT_EQ(big_hpd.get_decimal_point(), 123456789 + 1); + + __llvm_libc::internal::HighPrecisionDecimal big_negative_hpd = + __llvm_libc::internal::HighPrecisionDecimal("1e-123456789"); + + // Same, but since the number is negative the net result is -123456788 + EXPECT_EQ(big_negative_hpd.get_decimal_point(), -123456789 + 1); +}