This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of C++20 status.

3248. std::format #b, #B, #o, #x, and #X presentation types misformat negative numbers

Section: 22.14.2.2 [format.string.std] Status: C++20 Submitter: Richard Smith Opened: 2019-08-01 Last modified: 2021-02-25

Priority: 2

View other active issues in [format.string.std].

View all other issues in [format.string.std].

View all issues with C++20 status.

Discussion:

According to both the specification for '#' and the presentation types b, B, o, x, and X (which redundantly duplicate the rule for the relevant prefixes), the string 0b, 0B, 0, 0x, or 0X is prefixed to the result of to_chars. That means:

std::format("{0:#b} {0:#B} {0:#o} {0:#x} {0:#X}", -1)

produces

"0b-1 0B-1 0-1 0x-1 0X-1"

I assume that's a bug?

(Additionally, if the + specifier is used, there appears to be no specification of where the sign is inserted into the output.)

Victor Zverovich:

Yes. I suggest replacing

adds the respective prefix "0b" ("0B"), "0", or "0x" ("0X") to the output value

with something like

inserts the respective prefix "0b" ("0B"), "0", or "0x" ("0X") to the output value after the sign, if any,

I think the duplicate wording in the presentation types b, B, o, x, and X can be dropped.

Regarding the + specifier problem: How about adding

The sign is inserted before the output of to_chars.

?

[2019-08-21 Priority set to 2 based on reflector discussion]

Previous resolution [SUPERSEDED]:

This wording is relative to N4830.

  1. Modify the sign options Table [tab:format.sign] in 22.14.2.2 [format.string.std] as indicated:

    Table 59: Meaning of sign options [tab:format.sign]
    Option Meaning
    '+' Indicates that a sign should be used for both non-negative and negative numbers. The sign is inserted before the output of to_chars.
    '-' Indicates that a sign should be used only for negative numbers (this is the default behavior).
    space Indicates that a leading space should be used for non-negative numbers, and a minus sign for negative numbers.
  2. Modify [format.string] as indicated:

    -6 The # option causes the alternate form to be used for the conversion. This option is only valid for arithmetic types other than charT and bool or when an integer presentation type is specified. For integral types, the alternate form addsinserts the base prefix (if any) specified in Table [tab:format.type.int] to the output value after the sign, if any. […]

[2019-08-21; Victor Zverovich provides improved wording]

Previous resolution [SUPERSEDED]:

This wording is relative to N4830.

  1. Modify the sign options Table [tab:format.sign] in 22.14.2.2 [format.string.std] as indicated:

    Table 59: Meaning of sign options [tab:format.sign]
    Option Meaning
    '+' Indicates that a sign should be used for both non-negative and negative numbers. The + sign is inserted before the output of to_chars for non-negative numbers other than the negative zero. [Note: For negative numbers and the negative zero the output of to_chars will already contain the sign so no additional transformation is performed. — end note]
    '-' Indicates that a sign should be used only for negative numbers (this is the default behavior).
    space Indicates that a leading space should be used for non-negative numbers, and a minus sign for negative numbers.
  2. Modify [format.string] as indicated:

    -6- The # option causes the alternate form to be used for the conversion. This option is only valid for arithmetic types other than charT and bool or when an integer presentation type is specified. For integral types, the alternate form addsinserts the base prefix (if any) specified in Table [tab:format.type.int] to the output value after the sign character (possibly space) if there is one, or before the output of to_chars otherwise. […]

[2020-02-13, Prague]

LWG made some improvements to the wording.

[2020-02 Status to Immediate on Thursday night in Prague.]

Proposed resolution:

This wording is relative to N4849.

  1. Modify the sign options Table [tab:format.sign] in 22.14.2.2 [format.string.std] as indicated:

    Table 58: Meaning of sign options [tab:format.sign]
    Option Meaning
    '+' Indicates that a sign should be used for both non-negative and negative numbers. The + sign is inserted before the output of to_chars for non-negative numbers other than negative zero. [Note: For negative numbers and negative zero the output of to_chars will already contain the sign so no additional transformation is performed. — end note]
    '-' Indicates that a sign should be used only for negative numbers (this is the default behavior).
    space Indicates that a leading space should be used for non-negative numbers, and a minus sign for negative numbers.
  2. Modify [format.string] as indicated:

    -6- The # option causes the alternate form to be used for the conversion. This option is only valid for arithmetic types other than charT and bool or when an integer presentation type is specified, and not otherwise. For integral types, the alternate form addsinserts the base prefix (if any) specified in Table [tab:format.type.int] tointo the output value after the sign character (possibly space) if there is one, or before the output of to_chars otherwise. […]