std :: scientific是否总是对浮点数产生归一化的科学计数法? [英] Does std::scientific always result in normalized scientific notation for floating-point numbers?

查看:103
本文介绍了std :: scientific是否总是对浮点数产生归一化的科学计数法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

科学符号定义了如何使用符号,数字和指数来显示数字,但并未说明可视化已标准化.

Scientific notation defines how numbers should be displayed using a sign, a number and an exponent but it does not state that the visualization is normalized.

示例: -2.34e-2 (规范化科学计数法)与 -0.234e-1 (科学计数法)

An example: -2.34e-2 (normalized scientific notation) is the same as -0.234e-1 (scientific notation)

我可以依靠下面的代码始终产生标准化的结果吗?编辑:答案中指出的NAN和INF除外.

Can I rely on the following code always producing the normalized outcome? except NAN and INF as pointed out in the answers.

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().

If yes, please list a section in the C++ documentation/standard stating that it is not platform/implementation-defined. Since the value of 0 is also represented differently I'm afraid that certain very small numbers (denormalized?!) could be visualized differently. On my platform with my compiler it currently works for std::numeric_limits::min(), denorm_min().

注意:我用它来查找数字的数量级,而不会弄乱浮点数分析的所有古怪细节.我想要标准库为我做:-)

Note: I use this to find the order of magnitude of a number without messing with all the quirky details of floating point number analysis. I wanted the standard library do it for me :-)

推荐答案

是,除了零,无穷大和NaN.

Yes, except for zero, infinity and NaN.

C ++标准是指用于格式化的C标准,需要标准化的科学符号.

The C++ standard refers to the C standard for formatting, which requires normalized scientific notation.

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 ,...,则格式转换会像执行以下代码一样进行片段:

    Effects: The classes num_­get<> and num_­put<> handle locale-dependent numeric formatting and parsing. These inserter functions use the imbued locale value to perform numeric formatting. When val is of type ..., double, long double, ..., the formatting conversion occurs as if it performed the following code fragment:

    bool failed = use_facet<
      num_put<charT, ostreambuf_iterator<charT, traits>>
        >(getloc()).put(*this, *this, fill(), val).failed();
    

    val 的类型为 float 时,格式转换就好像执行了以下代码片段一样:

    When val is of type float the formatting conversion occurs as if it performed the following code fragment:

    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:

    • Stage 1:

    阶段1的第一步是确定转化说明符.描述此确定的表使用以下局部变量

    The first action of stage 1 is to determine a conversion specifier. The tables that describe this determination use the following local variables

    fmtflags flags = str.flags();
    fmtflags floatfield = (flags & (ios_base::floatfield));
    

    要从浮点类型进行转换,该函数将确定浮点转换说明符,如表70所示.

    For conversion from a floating-point type, the function determines the floating-point conversion specifier as indicated in Table 70.

    表70 —浮点转换

    | State                                            | stdio equivalent |
    | ------------------------------------------------ | ---------------- |
    | floatfield == ios_­base​::​scientific && !uppercase | %e               |
    | floatfield == ios_­base​::​scientific               | %E               |
    

    第1阶段结束时的表示形式由 char 组成,这些将通过调用 printf(s,val) 进行打印strong>其中 s 是上面确定的转换说明符.

    The representations at the end of stage 1 consists of the char's that would be printed by a call of printf(s, val) where s is the conversion specifier determined above.

  • C11 n1570 [7.21.6.1]:8.4

  • C11 n1570 [7.21.6.1]:8.4

    • e E

    表示浮点数的 double 参数在样式 [−] d.ddd e ±dd 其中有一位数字(如果参数不为零)在小数点字符之前以及等于精度后的数字;如果精度丢失,则取为6;否则,取0.如果精度为零,并且未指定#标志,则不带小数点字符出现.该值将四舍五入为适当的位数. E 转换说明符使用 E 而不是 e 产生一个数字介绍指数.指数始终至少包含两位数字,并且只需要表示位数所需的更多位数即可.如果值为零,指数为零.

    A double argument representing a floating-point number is converted in the style [−]d.ddde±dd, where there is one digit (which is nonzero if the argument is nonzero) before the decimal-point character and the number of digits after it is equal to the precision; if the precision is missing, it is taken as 6; if the precision is zero and the # flag is not specified, no decimal-point character appears. The value is rounded to the appropriate number of digits. The E conversion specifier produces a number with E instead of e introducing the exponent. The exponent always contains at least two digits, and only as many more digits as necessary to represent the exponent. If the value is zero, the exponent is zero.

    表示无穷大或NaN的 double 参数以 f F 转换说明符的样式进行转换.

    A double argument representing an infinity or NaN is converted in the style of an f or F conversion specifier.

  • 这篇关于std :: scientific是否总是对浮点数产生归一化的科学计数法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆