如何格式化浮点值,使其从不使用指数符号也不具有尾部零? [英] How do I format a floating point value so that it never uses exponent notation nor has trailing zeros?
问题描述
根据 ios_base操纵器,我基本上可以选择格式化不带指数符号的浮点数(十进制数)时,默认浮点数
和固定
。
但是,我想选择最大精度,这将产生很多<对于许多数字(例如 那么,我怎么能拥有我的馅饼,也可以吃它?也就是没有不必要的尾部零的非指数符号。 注意:我没有测试 1。
),固定
的尾部零,但避免使用指数符号。如果设置为 defaultfloat
,它将看起来最正确的时间,除非该值真的很小,但不是 0。
。在这种情况下,默认表示自己切换到科学记数法,这打破了格式化输出的接收器(因为它不知道 2.22045e-16
意味着什么。 / p>
defaultfloat
flag,因为我的gcc似乎没有实现那个标志(但),但我认为这是默认设置适用,而没有使用任何标志我做了检查 fixed
flag
这是一个正确的方法来做这与stdlib,这里是我的包装。
template< typename T>
struct FpFormat {
template< typename Stream>
static Stream& setfmt(Stream& str){
return str;
}
template< typename String>
static String const& untrail(String const& str){
return str;
}
};
template< typename T>
struct FpFormatFloats {
template< typename Stream>
static auto setfmt(Stream& str) - > decltype(str << std :: fixed<< std :: setprecision(std :: numeric_limits< T> :: digits10)){
return str< std :: fixed<< std :: setprecision(std :: numeric_limits< T> :: digits10);
}
template< typename String>
static String untrail(String str){
if(str.find('。')== String :: npos)
return str;
return([](String s){
return String(s.begin(),s.begin()+(s.back()=='。')? ()-1):s.size());
})(str.substr(0,(str +0)。find_last_not_of('0')+ 1)
}
};
模板<> struct FpFormat< float> :FpFormatFloats< float> {};
模板<> struct FpFormat< double> :FpFormatFloats< double> {};
模板<> struct FpFormat< long double> :FpFormatFloats< long double> {};
template< typename T>
std :: string toString(T x){
std :: stringstream str;
FpFormat< T> :: setfmt(str)<< X;
return FpFormat< T> :: untrail(str.str());
}
According to ios_base manipulators, I basically have the choice between defaultfloat
and fixed
when formatting floating point numbers without exponent notation (with decimal numbers).
However, I want to choose the maximum precision which would produce a lot trailing zeros for fixed
for many numbers (e.g. 1.
) but avoid ever using the exponent notation. If set to defaultfloat
, it will look right most of the time, unless the value is really really small, yet not 0.
. In that case, the default representation switches to scientific notation on its own, which breaks the receiver of the formatted output (since it has no clue what 2.22045e-16
means.
So, how can I have my pie and eat it, too? That is, non-exponent notation without unnecessary trailing zeroes.
Note: I did not test the effect of the defaultfloat
flag, since my gcc doesn't seem to implement that flag (yet), but I assume it is the default setting which applies without using any flag. I did check the fixed
flag, which does behave as expected.
Since there doesn't seem to be a proper way to do this with the stdlib, here's my wrapper.
template <typename T>
struct FpFormat {
template <typename Stream>
static Stream& setfmt(Stream& str) {
return str;
}
template <typename String>
static String const& untrail(String const& str) {
return str;
}
};
template <typename T>
struct FpFormatFloats {
template <typename Stream>
static auto setfmt(Stream& str) -> decltype(str << std::fixed << std::setprecision(std::numeric_limits<T>::digits10)) {
return str << std::fixed << std::setprecision(std::numeric_limits<T>::digits10);
}
template <typename String>
static String untrail(String str) {
if (str.find('.') == String::npos)
return str;
return ([](String s){
return String(s.begin(),s.begin()+((s.back() == '.')?(s.size()-1):s.size()));
})(str.substr(0,(str+"0").find_last_not_of('0')+1));
}
};
template <> struct FpFormat<float> : FpFormatFloats<float> {};
template <> struct FpFormat<double> : FpFormatFloats<double> {};
template <> struct FpFormat<long double> : FpFormatFloats<long double> {};
template <typename T>
std::string toString(T x) {
std::stringstream str;
FpFormat<T>::setfmt(str) << x;
return FpFormat<T>::untrail(str.str());
}
这篇关于如何格式化浮点值,使其从不使用指数符号也不具有尾部零?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!