diff --git a/libc/stdio/fmt.c b/libc/stdio/fmt.c index 72335a580..e00593ff6 100644 --- a/libc/stdio/fmt.c +++ b/libc/stdio/fmt.c @@ -1497,9 +1497,13 @@ int __fmt(void *fn, void *arg, const char *format, va_list va, int *wrote) { i1 = prec1 & 7; k = prec1 >> 3; __FMT_PUT(alphabet[(fpb.bits[k] >> 4 * i1) & 0xf]); - if (prec1 > 0 || prec > 0) { + + // decimal-point character appears if the precision isn't 0 + // or the # flag is specified + if (prec1 > 0 || prec > 0 || (flags & FLAGS_HASH)) { __FMT_PUT('.'); } + while (prec1 > 0) { if (--i1 < 0) { if (--k < 0) diff --git a/test/libc/stdio/snprintf_test.c b/test/libc/stdio/snprintf_test.c index 358095e30..e3f7a1aa7 100644 --- a/test/libc/stdio/snprintf_test.c +++ b/test/libc/stdio/snprintf_test.c @@ -217,12 +217,24 @@ TEST(snprintf, testLongDoubleRounding) { ASSERT_EQ(0, fesetround(previous_rounding)); } -void check_a_conversion_specifier_prec_1(const char *result_str, double value) { +void check_a_conversion_specifier_double(const char *fmt, const char *expected_str, double value) { char buf[30] = {0}; - int i = snprintf(buf, sizeof(buf), "%.1a", value); + int i = snprintf(buf, sizeof(buf), fmt, value); - ASSERT_EQ(strlen(result_str), i); - ASSERT_STREQ(result_str, buf); + ASSERT_EQ(strlen(expected_str), i); + ASSERT_STREQ(expected_str, buf); +} + +void check_a_conversion_specifier_long_double(const char *fmt, const char *expected_str, long double value) { + char buf[30] = {0}; + int i = snprintf(buf, sizeof(buf), fmt, value); + + ASSERT_EQ(strlen(expected_str), i); + ASSERT_STREQ(expected_str, buf); +} + +void check_a_conversion_specifier_prec_1(const char *expected_str, double value) { + check_a_conversion_specifier_double("%.1a", expected_str, value); } TEST(snprintf, testAConversionSpecifierRounding) { @@ -247,6 +259,11 @@ TEST(snprintf, testAConversionSpecifier) { check_a_conversion_specifier_prec_1("0x1.6p+4", 0x1.68p+4); check_a_conversion_specifier_prec_1("0x1.ap+4", 0x1.98p+4); check_a_conversion_specifier_prec_1("0x1.ap+4", 0x1.a8p+4); + + check_a_conversion_specifier_double("%#a", "0x0.p+0", 0x0.0p0); + check_a_conversion_specifier_double("%#A", "0X0.P+0", 0x0.0p0); + check_a_conversion_specifier_long_double("%#La", "0x0.p+0", 0x0.0p0L); + check_a_conversion_specifier_long_double("%#LA", "0X0.P+0", 0x0.0p0L); } TEST(snprintf, apostropheFlag) {