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

Created on 2019-08-01.00:00:00, last changed 2019-08-04.19:34:00.

Messages

Date: 2019-08-04.19:34:00

Proposed resolution:

This wording is relative to the Post Cologne working draft.

  1. Modify the sign option table in [format.string] as indicated:

    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:

    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 integers, when binary, octal, or hexadecimal output is used, this option addsinserts the respective prefix "0b" ("0B"), "0", or "0x" ("0X") to the output value after the sign, if any. […]

  3. Modify the table for the available integer presentation types and their mapping to to_chars as indicated:

    Type Meaning
    'b' to_chars(first, last, value, 2); using the '#' option with this type adds the prefix "0b" to the output.
    'B' The same as 'b', except that the '#' option adds the prefix "0B" to the output.
    'd' to_chars(first, last, value).
    'o' to_chars(first, last, value, 8); using the '#' option with this type adds the prefix "0" to the output.
    'x' to_chars(first, last, value, 16); using the '#' option with this type adds the prefix "0x" to the output.
    'X' The same as 'x', except that it uses uppercase letters for digits above 9 and the '#' option adds the prefix "0X" to the output.
    […]
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
2019-08-04 19:34:00adminsetmessages: + msg10542
2019-08-01 00:00:00admincreate