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 @@ -112,13 +112,14 @@ private: bool should_round_up(int32_t roundToDigit) { - if (roundToDigit < 0 || roundToDigit >= this->num_digits) { + if (roundToDigit < 0 || + static_cast(roundToDigit) >= this->num_digits) { return false; } // If we're right in the middle and there are no extra digits if (this->digits[roundToDigit] == 5 && - roundToDigit + 1 == this->num_digits) { + static_cast(roundToDigit + 1) == this->num_digits) { // Round up if we've truncated (since that means the result is slightly // higher than what's represented.) @@ -127,6 +128,9 @@ } // If this exactly halfway, round to even. + if (roundToDigit == 0) + // When the input is ".5". + return false; return this->digits[roundToDigit - 1] % 2 != 0; } // If there are digits after roundToDigit, they must be non-zero since we 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 @@ -36,6 +36,17 @@ EXPECT_EQ(hpd.get_decimal_point(), 1); } +TEST(LlvmLibcHighPrecisionDecimalTest, ShouldRoundup) { + __llvm_libc::internal::HighPrecisionDecimal hpd = + __llvm_libc::internal::HighPrecisionDecimal(".5"); + uint8_t *digits = hpd.get_digits(); + + EXPECT_EQ(digits[0], uint8_t(5)); + EXPECT_EQ(hpd.get_num_digits(), 1u); + EXPECT_EQ(hpd.get_decimal_point(), 0); + EXPECT_EQ(hpd.round_to_integer_type(), 0); +} + TEST(LlvmLibcHighPrecisionDecimalTest, SmallShift) { __llvm_libc::internal::HighPrecisionDecimal hpd = __llvm_libc::internal::HighPrecisionDecimal("1.2345"); diff --git a/libc/test/src/__support/str_to_float_test.cpp b/libc/test/src/__support/str_to_float_test.cpp --- a/libc/test/src/__support/str_to_float_test.cpp +++ b/libc/test/src/__support/str_to_float_test.cpp @@ -232,6 +232,11 @@ simple_decimal_conversion_test( "1.4012984643248170709237295832899161312802619418765e-45", 0x1, 0, ERANGE); + simple_decimal_conversion_test( + "7." + "006492321624085354618647916449580656401309709382578858785341419448955413" + "42930300743319094181060791015625e-46", + 0x0, 0, ERANGE); } TEST(LlvmLibcStrToFloatTest, SimpleDecimalConversionExtraTypes) {