首页 文章

IEEE 754浮点数的有效数字

提问于
浏览
1

Wiki Double-precision floating-point format说:

这给出了15-17个有效小数位数精度 . 如果具有最多15位有效数字的十进制字符串转换为IEEE 754双精度表示,然后转换回具有相同有效位数的字符串,则最终字符串应与原始字符串匹配 . 如果将IEEE 754双精度转换为具有至少17位有效数字的十进制字符串,然后再转换回双精度数,则最终数字必须与原始数字匹配 .

任何人都可以给我一些例子来说明转换如何与原始版本匹配,在哪种情况下它不会?

1 回答

  • 0

    有15位有效数字,从字符串到double和back ...

    std::istringstream iss("0.123456789012345");
    double d;
    iss >> d;
    std::ostringstream oss;
    oss << std::fixed << std::setprecision(15) << d;
    std::cout << "should be 0.123456789012345 but might have changed: " << oss.str() << '\n';
    

    注意:对于大约15个有效数字的初始输入字符串,上面的代码可能会输出不同的最终字符串 . 这里's a program that attempts to find a 15 digit string input for which the value isn' t通过转换为 double 保留,但是all values pass for GCC on coliru.stackedcrooked.com . 对于不同范围内的其他值,这不会失败 .

    #include <sstream>
    #include <iostream>
    #include <iomanip>
    
    int main()
    {
        int results = 0;
    
        for (unsigned long i = 0; i <= 999999999999999; ++i)
        {
            std::ostringstream oss;
            oss << "0." << std::setfill('0') << std::setw(15) << i;
            std::istringstream iss(oss.str());
            double d;
            iss >> d;
            std::ostringstream oss2;
            oss2 << std::fixed << std::setprecision(15) << d;
            if (oss.str() != oss2.str())
            {
                std::cout << "from " << oss.str() << '\n' << "  to " << oss2.str() << '\n';
                if (++results > 50) exit(0);
            }
        }
    }
    

    有17位有效数字,从double到string和back ...

    double d = 0.12345678901234567;
    std::ostringstream oss;
    oss << std::fixed << std::setprecision(17) << d;
    std::istringstream iss(oss.str());
    double d2;
    iss >> d2;
    std::cout << "d must equal d2: " << std::boolalpha << d == d2 << '\n';
    

    这应该永远不会从文本表示中恢复相同的 double 值 .

相关问题