I am trying to convert strings to double with std::from_chars, but I cannot get alignment with strtod when it comes to exponential numbers. The reproducer:
#include <string>
#include <iostream>
#include <charconv>
void xxx(std::string const A){
double x;
std::from_chars(&A[0],&A.back(),x,std::chars_format::scientific);
printf("%s,%.17g\n",A.c_str(),x);
}
void yyy(std::string const A){
printf("%s,%.17g\n",A.c_str(),strtod(&A[0],NULL));
}
int main(){
xxx(std::string("0.9226e-01"));
yyy(std::string("0.9226e-01"));
xxx(std::string("0.9226e-10"));
yyy(std::string("0.9226e-10"));
}
which produces output
0.9226e-01,0.92259999999999998
0.9226e-01,0.092259999999999995
0.9226e-10,0.092259999999999995
0.9226e-10,9.226e-11
I would say that strtod produces the correct results.
Happy to learn that I got it wrong.
Platform: linux g version: 12.2
Thanks and merry christmas
CodePudding user response:
Analyzes the character sequence [first,last) for a pattern described below.
The closing parenthesis means last
is excluded. Thus, the actual data that std::from_chars(&A[0], &A.back(), ...)
is processing are
"0.9226e-0"
"0.9226e-1"
The correct invocation:
void xxx(std::string const A){
double x;
std::from_chars(A.begin(), A.end(), x,std::chars_format::scientific);
printf("%s,%.17g\n", A.c_str(),x);
}
or
void xxx(std::string const A){
double x;
std::from_chars(&A[0], &A[0] A.size(), x,std::chars_format::scientific);
printf("%s,%.17g\n", A.c_str(),x);
}