diff --git a/include/fmt/format-inl.h b/include/fmt/format-inl.h index 0f9af8b6..b180051d 100644 --- a/include/fmt/format-inl.h +++ b/include/fmt/format-inl.h @@ -645,7 +645,7 @@ FMT_FUNC bool grisu2_format(Double value, buffer& buf, int precision, bool fixed, int& exp) { FMT_ASSERT(value >= 0, "value is negative"); if (value <= 0) { // <= instead of == to silence a warning. - if (precision < 0) { + if (precision < 0 || !fixed) { exp = 0; buf.push_back('0'); } else { diff --git a/include/fmt/format.h b/include/fmt/format.h index ed605679..9ef04db6 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -1161,7 +1161,7 @@ template It write_exponent(int exp, It it) { *it++ = static_cast(d[1]); } else { const char* d = data::DIGITS + exp * 2; - if (d[0] != '0') *it++ = static_cast(d[0]); + *it++ = static_cast(d[0]); *it++ = static_cast(d[1]); } return it; @@ -1198,12 +1198,14 @@ It grisu2_prettify(const char* digits, int size, int exp, It it, // 1234e-2 -> 12.34[0+] it = copy_str(digits, digits + full_exp, it); *it++ = static_cast('.'); - it = copy_str(digits + full_exp, digits + size, it); if (!params.trailing_zeros) { // Remove trailing zeros. - // TODO - // handler.remove_trailing('0'); - } else if (params.num_digits > size) { + while (size > full_exp && digits[size - 1] == '0') + --size; + return copy_str(digits + full_exp, digits + size, it); + } + it = copy_str(digits + full_exp, digits + size, it); + if (params.num_digits > size) { // Add trailing zeros. int num_zeros = params.num_digits - size; it = std::fill_n(it, num_zeros, static_cast('0')); @@ -2668,8 +2670,9 @@ template class basic_writer { const internal::gen_digits_params& params) : digits_(digits), sign_(sign), exp_(exp), params_(params) { int num_digits = static_cast(digits.size()); - int full_exp = num_digits + exp; - params_.fixed |= (full_exp - 1) >= -4 && (full_exp - 1) <= 10; + int full_exp = num_digits + exp - 1; + int precision = params.num_digits > 0 ? params.num_digits : 11; + params_.fixed |= full_exp >= -4 && full_exp < precision; auto it = internal::grisu2_prettify( digits.data(), num_digits, exp, internal::counting_iterator(), params_); @@ -2869,7 +2872,8 @@ void basic_writer::write_double(T value, const format_specs& spec) { int exp = 0; int precision = spec.has_precision() || !spec.type ? spec.precision : 6; bool use_grisu = fmt::internal::use_grisu() && - (!spec.type || handler.fixed) && + (spec.type != 'a' && spec.type != 'A' && + spec.type != 'e' && spec.type != 'E') && internal::grisu2_format(static_cast(value), buffer, precision, handler.fixed, exp); if (!use_grisu) internal::sprintf_format(value, buffer, spec); @@ -2894,7 +2898,8 @@ void basic_writer::write_double(T value, const format_specs& spec) { auto params = internal::gen_digits_params(); params.fixed = handler.fixed; params.num_digits = precision; - if (precision != 0) params.trailing_zeros = true; + params.trailing_zeros = + (precision != 0 && (handler.fixed || !spec.type)) || spec.has(HASH_FLAG); write_padded(as, grisu_writer{sign, buffer, exp, params}); } else { write_padded(as, double_writer{sign, buffer}); diff --git a/test/grisu-test.cc b/test/grisu-test.cc index f496f900..746e90ba 100644 --- a/test/grisu-test.cc +++ b/test/grisu-test.cc @@ -44,8 +44,8 @@ TEST(GrisuTest, Round) { TEST(GrisuTest, Prettify) { EXPECT_EQ("0.0001", fmt::format("{}", 1e-4)); - EXPECT_EQ("1e-5", fmt::format("{}", 1e-5)); - EXPECT_EQ("9.999e-5", fmt::format("{}", 9.999e-5)); + EXPECT_EQ("1e-05", fmt::format("{}", 1e-5)); + EXPECT_EQ("9.999e-05", fmt::format("{}", 9.999e-5)); EXPECT_EQ("10000000000.0", fmt::format("{}", 1e10)); EXPECT_EQ("1e+11", fmt::format("{}", 1e11)); EXPECT_EQ("12340000000.0", fmt::format("{}", 1234e7)); diff --git a/test/printf-test.cc b/test/printf-test.cc index eda15864..d5f14a98 100644 --- a/test/printf-test.cc +++ b/test/printf-test.cc @@ -252,8 +252,7 @@ TEST(PrintfTest, FloatPrecision) { safe_sprintf(buffer, "%.3e", 1234.5678); EXPECT_PRINTF(buffer, "%.3e", 1234.5678); EXPECT_PRINTF("1234.568", "%.3f", 1234.5678); - safe_sprintf(buffer, "%.3g", 1234.5678); - EXPECT_PRINTF(buffer, "%.3g", 1234.5678); + EXPECT_PRINTF("1.23e+03", "%.3g", 1234.5678); safe_sprintf(buffer, "%.3a", 1234.5678); EXPECT_PRINTF(buffer, "%.3a", 1234.5678); }