I'm investigating the replacing of doubles in our code with g++'s std::decimal::decimal32/64/128 types for purpose of currency amounts and prices, however I'm getting stuck on the point of how to best input and output the data. Specifically, there do not appear to be any routines for converting to/from a string, and the stringstream mechanisms do not compile for these types. The only way I see doing this is to use double as an intermediate type, however surely this at least partially defeats the purpose of using the decimal types if we're always inputting and outputting via doubles?
I'm sure I'm not understanding something here so would welcome some feedback on how best to use these types.
Edit:
I have hacked together a couple of input/output routines, however I'm not really satisfied with either. The input is hardly robust (no scientific notation support) and the output routine is simplistic, not to mention inefficient due to the double conversion.
#define MAX_DEC_LEN 17
std::decimal::decimal64 FromString(const char* str)
{
if (strlen(str) > MAX_DEC_LEN)
throw std::runtime_error("bad input");
char buf[MAX_DEC_LEN+1];
strncpy(buf, str, MAX_DEC_LEN+1);
char* point(NULL);
if ((point = strchr(buf, '.')) != NULL)
*(point++) = '';
std::decimal::decimal64 ret(atoi(buf));
if (point != NULL && *point != '')
{
int exponent(strlen(point));
long long unsigned coeff(atoi(point));
std::decimal::decimal64 d2(std::decimal::make_decimal64(coeff, -exponent));
if (*buf == '-')
ret -= d2;
else
ret += d2;
}
return ret;
}
std::string ToString(std::decimal::decimal64 dec)
{
double d(std::decimal::decimal_to_double(dec));
std::ostringstream oss;
oss << std::fixed << std::setprecision(6) << d;
return oss.str();
}
I'm really after something better for both of these, plus a round (to a particular precision) to round things off (pardon the pun)
See Question&Answers more detail:os