diff --git a/include/fmt/format-inl.h b/include/fmt/format-inl.h index ed87209e..511c8d85 100644 --- a/include/fmt/format-inl.h +++ b/include/fmt/format-inl.h @@ -2246,7 +2246,8 @@ FMT_HEADER_ONLY_CONSTEXPR20 int format_float(Float value, int precision, precision = handler.precision; } } else { - exp = static_cast(std::log10(value)); + // Use floor because 0.9 = 9e-1. + exp = static_cast(std::floor(std::log10(value))); if (fixed) adjust_precision(precision, exp + 1); } if (use_dragon) { diff --git a/include/fmt/format.h b/include/fmt/format.h index 55cd4409..08c1f7d0 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -2256,6 +2256,8 @@ FMT_CONSTEXPR20 auto write(OutputIt out, T value, throw_format_error("number is too big"); else ++precision; + } else if (fspecs.format != float_format::fixed && precision == 0) { + precision = 1; } if (const_check(std::is_same())) fspecs.binary32 = true; if (!std::numeric_limits::is_iec559 || std::numeric_limits::digits > 64) diff --git a/test/format-test.cc b/test/format-test.cc index 72423017..e7b23b7c 100644 --- a/test/format-test.cc +++ b/test/format-test.cc @@ -948,6 +948,9 @@ TEST(format_test, precision) { EXPECT_THAT(outputs, testing::Contains(fmt::format("{:.838A}", -2.14001164E+38))); + auto ld = 8.43821965335442234493E-4933L; + EXPECT_EQ(fmt::format("{:.0}", ld), ld != 0 ? "8e-4933" : "0"); + EXPECT_EQ("123.", fmt::format("{:#.0f}", 123.0)); EXPECT_EQ("1.23", fmt::format("{:.02f}", 1.234)); EXPECT_EQ("0.001", fmt::format("{:.1g}", 0.001));