[libc-commits] [PATCH] D158118: [libc] Fix HPD on extremely long numbers
Michael Jones via Phabricator via libc-commits
libc-commits at lists.llvm.org
Thu Aug 17 15:00:20 PDT 2023
michaelrj updated this revision to Diff 551285.
michaelrj added a comment.
I was wrong. I've added tests. They don't test the behavior directly, but they're the best I can do without 100k of zeroes. Also I increased the maximum exponent HPD will store to 2^30, which is ~1 billion. If we discover this limit is too low I will be shocked.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D158118/new/
https://reviews.llvm.org/D158118
Files:
libc/src/__support/high_precision_decimal.h
libc/test/src/__support/high_precision_decimal_test.cpp
Index: libc/test/src/__support/high_precision_decimal_test.cpp
===================================================================
--- libc/test/src/__support/high_precision_decimal_test.cpp
+++ libc/test/src/__support/high_precision_decimal_test.cpp
@@ -391,3 +391,18 @@
EXPECT_EQ(hpd.round_to_integer_type<UInt128>(), 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);
+}
Index: libc/src/__support/high_precision_decimal.h
===================================================================
--- libc/src/__support/high_precision_decimal.h
+++ 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<int32_t>(numString, 10);
- if (add_to_exp > 100000) {
- add_to_exp = 100000;
- } else if (add_to_exp < -100000) {
- add_to_exp = -100000;
+ auto result = strtointeger<int32_t>(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<int64_t>(this->decimal_point) +
+ static_cast<int64_t>(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<int32_t>(temp_exponent);
}
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D158118.551285.patch
Type: text/x-patch
Size: 2404 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/libc-commits/attachments/20230817/56b2d304/attachment.bin>
More information about the libc-commits
mailing list