Title
std::fixed ignores std::uppercase
Status
voting
Section
[facet.num.put.virtuals]
Submitter
Jonathan Wakely

Created on 2024-04-30.00:00:00 last changed yesterday

Messages

Date: 2024-09-19.09:48:14

Proposed resolution:

This wording is relative to N4981.

  1. Modify [facet.num.put.virtuals] as indicated:

    Table 114 – Floating-point conversions [tab:facet.num.put.fp]
    State `stdio` equivalent
    `floatfield == ios_base::fixed` && !uppercase `%f`
    `floatfield == ios_base::fixed` `%F`
    floatfield == ios_base::scientific && !uppercase `%e`
    floatfield == ios_base::scientific `%E`
    floatfield == (ios_base::fixed | ios_base::scientific)` && !uppercase `%a`
    floatfield == (ios_base::fixed | ios_base::scientific) `%A`
    `!uppercase` `%g`
    otherwise `%G`
Date: 2024-09-15.00:00:00

[ 2024-09-19; Reflector poll ]

Set status to Tentatively Ready after eight votes in favour during reflector poll.

Date: 2024-09-15.00:00:00

[ 2024-09-17; LEWG mailing list vote ]

Set status to Open after LEWG approved the proposed change.

Date: 2024-05-15.00:00:00

[ 2024-05-08; Reflector poll ]

Set priority to 3 after reflector poll. Send to LEWG.

Date: 2024-05-09.14:20:05

In Table 114 – Floating-point conversions [tab:facet.num.put.fp] we specify that a floating-point value should be printed as if by `%f` when (flags & floatfield) == fixed. This ignores whether `uppercase` is also set in `flags`, meaning there is no way to use the conversion specifier `%F` that was added to `printf` in C99.

That's fine for finite values, because 1.23 in fixed format has no exponent character and no hex digits that would need to use uppercase. But `%f` and `%F` are not equivalent for non-finite values, because `%F` prints `"NAN"` and `"INF"` (or `"INFINITY"`). It seems there is no way to print `"NAN"` or `"INF"` using `std::num_put`.

Libstdc++ and MSVC print `"inf"` for the following code, but libc++ prints `"INF"` which I think is non-conforming:

    std::cout << std::uppercase << std::fixed << std::numeric_limits<double>::infinity();

The libc++ behaviour seems more useful and less surprising.

History
Date User Action Args
2024-11-19 16:09:07adminsetstatus: ready -> voting
2024-09-19 09:48:14adminsetmessages: + msg14387
2024-09-19 09:48:14adminsetstatus: open -> ready
2024-09-17 09:45:41adminsetmessages: + msg14365
2024-09-17 09:45:41adminsetstatus: lewg -> open
2024-05-08 09:28:41adminsetmessages: + msg14114
2024-05-08 09:28:41adminsetstatus: new -> lewg
2024-04-30 21:59:59adminsetmessages: + msg14090
2024-04-30 00:00:00admincreate