Skip to content

Bug: format decimal with thousands sep #353

Closed
@shestakovda

Description

@shestakovda

Hi! Thanks for good lib!

But I think there are some bugs, is that so?

Test code:

    setlocale(LC_NUMERIC, "en_US.UTF-8");
    // good
    assert(fmt::format("{:n}", 123) == "123");
    assert(fmt::format("{:n}", 12345) == "12,345");
    assert(fmt::format("{:n}", 123456) == "123,456");
    assert(fmt::format("{:n}", 1234567) == "1,234,567");
    assert(fmt::format("{:n}", 12345678) == "12,345,678");
    assert(fmt::format("{:n}", 123456789) == "123,456,789");
    // fail
    std::cout << fmt::format("{:n}", 1234) << std::endl;  // 11234
    assert(fmt::format("{:n}", 1234) == "1,234");
    std::cout << fmt::format("{:n}", 1234567890) << std::endl; // 11234,567,890
    assert(fmt::format("{:n}", 1234567890) == "1,234,567,890");

Seems to be an error in format.h:936: no thousands sep functor call. I think that it makes buffer to miss pointer position. This fix it for me (in format.h:934):

  unsigned index = static_cast<unsigned>(value * 2);
  *--buffer = Data::DIGITS[index + 1];
  thousands_sep(buffer);
  *--buffer = Data::DIGITS[index];
  thousands_sep(buffer);

And separator is "\xc2\xa0"; for "ru_RU.UTF-8" locale, so there is another mistake in format.h:2784 (need some additional brackets). The next code fixes it:

    unsigned size = static_cast<unsigned>(
          num_digits + sep.size() * ((num_digits - 1) / 3) );

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions