Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions libc/src/__support/float_to_string.h
Original file line number Diff line number Diff line change
Expand Up @@ -700,7 +700,11 @@ template <> class FloatToString<long double> {

const int SHIFT_AMOUNT = FLOAT_AS_INT_WIDTH + exponent;
static_assert(EXTRA_INT_WIDTH >= sizeof(long double) * 8);
float_as_fixed <<= SHIFT_AMOUNT;
if (SHIFT_AMOUNT > 0) {
float_as_fixed <<= SHIFT_AMOUNT;
} else {
float_as_fixed >>= -SHIFT_AMOUNT;
}

// If there are still digits above the decimal point, handle those.
if (cpp::countl_zero(float_as_fixed) <
Expand Down Expand Up @@ -769,7 +773,7 @@ template <> class FloatToString<long double> {
// The decimal representation of 2**(-i) will have exactly i digits after
// the decimal point.
const int num_requested_digits =
static_cast<int>((negative_block_index + 1) * BLOCK_SIZE);
static_cast<int>(negative_block_index * BLOCK_SIZE);

return num_requested_digits > -exponent;
}
Expand Down
12 changes: 12 additions & 0 deletions libc/test/src/stdio/sprintf_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1537,6 +1537,14 @@ TEST(LlvmLibcSPrintfTest, FloatDecimalLongDoubleConv) {
#if defined(LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80)

#ifndef LIBC_COPT_FLOAT_TO_STR_REDUCED_PRECISION
written = LIBC_NAMESPACE::sprintf(
buff, "%.75Lf",
0.0833333333333333333355920878593448009041821933351457118988037109375L);
ASSERT_STREQ_LEN(written, buff,
"0."
"08333333333333333333559208785934480090418219333514571189880"
"3710937500000000");

written = LIBC_NAMESPACE::sprintf(buff, "%Lf", 1e100L);
ASSERT_STREQ_LEN(written, buff,
"99999999999999999996693535322073426194986990198284960792713"
Expand Down Expand Up @@ -2976,6 +2984,10 @@ TEST(LlvmLibcSPrintfTest, FloatAutoLongDoubleConv) {
written = LIBC_NAMESPACE::sprintf(buff, "%Lg", 0xf.fffffffffffffffp+16380L);
ASSERT_STREQ_LEN(written, buff, "1.18973e+4932");

// Minimum normal
written = LIBC_NAMESPACE::sprintf(buff, "%Lg", 3.36210314311209350626E-4932L);
ASSERT_STREQ_LEN(written, buff, "3.3621e-4932");

written = LIBC_NAMESPACE::sprintf(buff, "%Lg", 0xa.aaaaaaaaaaaaaabp-7L);
ASSERT_STREQ_LEN(written, buff, "0.0833333");

Expand Down
Loading