我正在调查我们的代码中使用g的std :: decimal :: decimal32 / 64/128类型替换双打的货币金额和价格,但是我陷入了如何最好的输入和输出数据.具体来说,似乎没有任何用于转换到/从字符串的例程,并且stringstream机制不会为这些类型编译.我看到这样做的唯一方法是使用double作为中间类型,但是如果我们总是通过双打输入和输出,这至少部分地不符合使用十进制类型的目的.
我相信我不了解这里的东西,所以欢迎有关如何最好地使用这些类型的一些反馈.
编辑:
我已经把几个输入/输出程序一起入侵了,但是我并不满意.输入是不健全的(没有科学的符号支持)和输出例程是简单的,更不用说由于双重转换效率低下.
#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++) = '\0'; std::decimal::decimal64 ret(atoi(buf)); if (point != NULL && *point != '\0') { 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(); }
我真的在为这两个事情做些更好的事情,再加上一个回合(以一个特定的精确度),把事情完成(原谅双关语)
解决方法
Decimal TR分别定义了3.2.10和3.2.11节中输入和输出的重载.从它的外观,它们没有被gcc实现. gcc中的十进制支持是通过libdecnum来实现的,它提供了从字符串转换到字符串的例程.我将创建一个使用它们的I / O操作符的简单实现来开始.
在2012-10-17编辑:查看格式化gcc的库(std :: decimal :: decimal64和family)中的十进制值,显示gcc不幸的是不安装decNumber库头或库.此外,decNumber的其他来源与gcc的版本不一致.因此,我发现到目前为止得到十进制格式的唯一方法是在编译gcc期间使用显式声明和使用库构建.
简单的部分是源,虽然是一个相当简单的实现.首先,将进入适当标题的声明,例如<十进制/十进制计算值:
std::ostream& operator<< (std::ostream&,std::decimal::decimal32 const&); std::ostream& operator<< (std::ostream&,std::decimal::decimal64 const&); std::ostream& operator<< (std::ostream&,std::decimal::decimal128 const&);
一些相当简单的实现某些格式化的东西,虽然没有任何选择可能如下所示:
extern "C" char* decimal32ToString(std::decimal::decimal32 const*,char*); extern "C" char* decimal64ToString(std::decimal::decimal64 const*,char*); extern "C" char* decimal128ToString(std::decimal::decimal128 const*,char*); std::ostream& operator<< (std::ostream& out,std::decimal::decimal32 const& value) { char buffer[128]; decimal32ToString(&value,buffer); return out << buffer; } std::ostream& operator<< (std::ostream& out,std::decimal::decimal64 const& value) { char buffer[128]; decimal64ToString(&value,std::decimal::decimal128 const& value) { char buffer[128]; decimal128ToString(&value,buffer); return out << buffer; }
有了这一点,仍然有一个问题,我没有使用小数来构建任何东西,除非使用一些优化级别,即-O1(或更高).除非使用优化,否则是未引用的符号,但与打印值完全无关.要获取实现中使用的函数的定义,我需要链接到正在构建gcc时创建的libdecnumber.a库:
g++ -o prog decimal-io.cpp main.cpp <gcc-build-root>/libdecnumber/libdecnumber.a
除此之外,我自己实现了Decimal TR与some extension,并将其基于decnumber库并正确实现I / O.我的实施希望在某些时候公开发布,但不会很快.