科学记数法定义了如何使用符号,数字和指数显示数字,但它并未声明可视化是规范化的。
一个例子: -2.34e-2 (标准化科学记数法)与 -0.234e-1 (科学记数法)相同
我可以依赖以下代码始终产生标准化结果吗? 编辑,除了答案中指出的NAN和INF。
template<typename T>
static std::string toScientificNotation(T number, unsigned significantDigits)
{
if (significantDigits > 0) {
significantDigits--;
}
std::stringstream ss;
ss.precision(significantDigits);
ss << std::scientific << number;
return ss.str();
}
如果是,请列出C ++文档/标准中的一节,说明它不是平台/实现定义的。由于0的值也有不同的表示,我担心某些非常小的数字(非规范化的?!)可以被不同地显示出来。在我的平台上使用我的编译器,它目前适用于std :: numeric_limits :: min(),denorm_min()。
注意:我使用它来查找数字的数量级而不会弄乱浮点数分析的所有细节。我希望标准库为我做: - )
答案 0 :(得分:4)
我可以依赖以下代码始终产生规范化结果吗?
无法保证,不。更好地说:标准并没有像你希望的那样强有力的保证。
std::scientific
仅在以下相关部分引用:
ios_base& scientific(ios_base& str);
效果:致电
str.setf(ios_base::scientific, ios_base::floatfield)
返回:str
。
| Element | Effect(s) if set | | ... | ... | | scientific | generates floating-point output in scientific notation | | ... | ... |
答案 1 :(得分:2)
是的,除了零,无穷大和NaN。
C ++标准是指格式化的C标准,需要标准化的科学记数法。
ios_base& scientific(ios_base& str);
效果:致电
str.setf(ios_base::scientific, ios_base::floatfield)
。返回:
str
。
[ostream.inserters.arithmetic]/1(部分)
operator<<(float val); operator<<(double val); operator<<(long double val);
效果:类
num_get<>
和num_put<>
处理依赖于区域设置的数字格式和解析。这些插入器函数使用嵌入式locale
值来执行数字格式设置。如果val
的类型为...,double
,long double
,...,则格式转换就像执行以下代码片段一样:bool failed = use_facet< num_put<charT, ostreambuf_iterator<charT, traits>> >(getloc()).put(*this, *this, fill(), val).failed();
val
类型为float
时,格式转换就像执行以下代码片段一样:bool failed = use_facet< num_put<charT, ostreambuf_iterator<charT, traits>> >(getloc()).put(*this, *this, fill(), static_cast<double>(val)).failed();
[facet.num.put.virtuals]/1:5.1(部分)
第1阶段:
第1阶段的第一个操作是确定转换说明符。描述此确定的表使用以下局部变量
fmtflags flags = str.flags(); fmtflags floatfield = (flags & (ios_base::floatfield));
对于从浮点类型的转换,该函数确定浮点转换说明符,如表70所示。
表70 - 浮点转换
| State | stdio equivalent | | ------------------------------------------------ | ---------------- | | floatfield == ios_base::scientific && !uppercase | %e | | floatfield == ios_base::scientific | %E |
第1阶段结束时的陈述包含
char
的,这些将通过调用printf(s, val)
打印,其中s
是转化上面确定的说明符。
C11 n1570 [7.21.6.1]:8.4
<强>电子强>,<强>电子强>
表示浮点数的
double
参数在。中转换 style [ - ] d.ddd e ±dd ,哪里有一位数字(如果是 参数非零)小数点前的字符和数字 等于精度后的数字;如果精度丢失,则取6;如果精度为零且未指定#标志,则不包含小数点 角色出现。该值四舍五入到适当的位数。 E 转换说明符生成的数字 E 而不是 e 介绍指数。指数始终包含至少两位数, 并且只需要表示指数所需的数字。 如果 值为零,指数为零。表示无穷大或NaN的
double
参数将以 f 或 F 转换说明符的样式进行转换。