Is std::from_chars supposed to handle uppercase hexadecimal exponents?
Asked Answered
P

1

8

On upgrading to Ubuntu 22.04 (amd64), I have noticed that the following code has started to give the result 1.4375 instead of the expected value 1472:

#include <charconv>
#include <iostream>
#include <string_view>

int main()
{
    std::string_view src{"1.7P10"};
    double value;
    auto result = std::from_chars(src.data(), src.data() + src.size(), value, std::chars_format::hex);
    std::cout << value << '\n';
}

I get the expected result if I change the P character in the source to lowercase p. Both uppercase and lowercase work with std::strtod.

Is std::from_chars supposed to fail with uppercase exponent characters, or is this a bug in g++/libstdc++?

Command line used to compile:

g++ -std=c++17 test.cpp

(optimisation level appears to have no effect)

Output of g++ --version:

g++ (Ubuntu 11.2.0-19ubuntu1) 11.2.0
Copyright (C) 2021 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Poetess answered 30/4, 2022 at 13:33 Comment(0)
D
8

Is std::from_chars supposed to fail with uppercase exponent characters, or is this a bug in g++/libstdc++?

This is a bug of libstdc++, submitted 105441.

From [charconv.from.chars], emphasis mine

from_chars_result from_chars(const char* first, const char* last, double& value,
                             chars_format fmt = chars_format::general);
  • Preconditions: fmt has the value of one of the enumerators of chars_­format.
  • Effects: The pattern is the expected form of the subject sequence in the "C" locale, as described for strtod, except that
    • the sign '+' may only appear in the exponent part;
    • if fmt has chars_­format​::​scientific set but not chars_­format​::​fixed, the otherwise optional exponent part shall appear;
    • if fmt has chars_­format​::​fixed set but not chars_­format​::​scientific, the optional exponent part shall not appear; and
    • if fmt is chars_­format​::​hex, the prefix "0x" or "0X" is assumed.

So in your example, "1.7P10" should be a valid pattern, and the result of from_chars should be equivalent to strtod("0x1.7P10").

Defant answered 30/4, 2022 at 15:53 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.