Title
std::format #b, #B, #o, #x, and #X presentation types misformat negative numbers
Status
c++20
Section
[format.string.std]
Submitter
Richard Smith

Created on 2019-08-01.00:00:00 last changed 46 months ago

Messages

Date: 2020-02-14.11:24:43

Proposed resolution:

This wording is relative to N4849.

  1. Modify the sign options Table [tab:format.sign] in [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. […]

Date: 2020-02-14.11:24:43

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

Date: 2020-02-15.00:00:00

[ 2020-02-13, Prague ]

LWG made some improvements to the wording.

Date: 2019-08-15.00:00:00

[ 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 [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. […]

Date: 2019-08-21.00:00:00

[ 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 [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. […]

Date: 2019-08-01.00:00:00

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.

?

History
Date User Action Args
2021-02-25 10:48:01adminsetstatus: wp -> c++20
2020-02-24 16:02:59adminsetstatus: immediate -> wp
2020-02-14 11:24:43adminsetmessages: + msg11117
2020-02-14 11:24:43adminsetstatus: new -> immediate
2020-02-13 19:42:16adminsetmessages: + msg11083
2019-08-21 19:26:24adminsetmessages: + msg10578
2019-08-21 19:26:24adminsetmessages: + msg10577
2019-08-04 19:34:00adminsetmessages: + msg10542
2019-08-01 00:00:00admincreate