【问题标题】:std::cout with floating number带有浮点数的 std::cout
【发布时间】:2015-11-22 12:34:01
【问题描述】:

我正在使用 Visual Studio 2015 打印两个浮点数:

double d1 = 1.5;
double d2 = 123456.789;

std::cout << "value1: " << d1 << std::endl;
std::cout << "value2: " << d2 << std::endl;

std::cout << "maximum number of significant decimal digits (value1): " << -std::log10(std::nextafter(d1, std::numeric_limits<double>::max()) - d1) << std::endl;
std::cout << "maximum number of significant decimal digits (value2): " << -std::log10(std::nextafter(d2, std::numeric_limits<double>::max()) - d2) << std::endl;

这将打印以下内容:

value1: 1.5
value2: 123457
maximum number of significant decimal digits (value1): 15.6536
maximum number of significant decimal digits (value2): 10.8371

为什么将 123457 打印为值 123456.789?当 std::cout 不使用 std::setprecision() 时,ANSI C++ 规范是否允许显示任何浮点数?

【问题讨论】:

  • " ANSI C++ 规范是否允许在不使用 std::setprecision() 的情况下使用 std::cout 时显示浮点数的任何内容?"是的。
  • @Hermantas,对,我的意思是 std::cout。
  • @Mats,为什么规范在这个主题上如此含糊?如果规范更具体(例如打印带有有效数字的浮点数),它将对开发人员有所帮助。类似 printf("%.16g\n", d).
  • 默认精度为 6,和 printf 一样。
  • @Bo,正确的 std::cout.precision() 给出 6。因此规范定义明确。谢谢。

标签: c++


【解决方案1】:

四舍五入的发生是因为 C++ 标准,可以通过写作看到 std::cout&lt;&lt;std::cout.precision();

输出屏幕将显示 6,这表明 cout 语句将打印的默认有效位数为 6。这就是它自动将浮点数四舍五入为 6 位的原因。

【讨论】:

    【解决方案2】:

    您所指出的实际上是标准化委员会应该考虑的关于 C++ 中的standard iostream 的许多事情之一。当你写这些东西时效果很好:-

    printf ("%f\n", d2);
    

    但不是std::cout,您需要使用std::setprecision,因为它的格式类似于使用%g 而不是printf 中的%f。所以你需要写:-

    std::cout << std::setprecision(10) << "value2: " << d2 << std::endl;
    

    但如果你不喜欢这种方法并且使用的是 C++11(及更高版本),那么你也可以编写:-

    std::cout << "value2: " << std::to_string(d2) << std::endl;
    

    这将为您提供与printf ("%f\n", d2); 相同的结果。

    更好的方法是使用std::fixed 取消std::cout 中发生的舍入:-

    #include <iostream>
    #include <iomanip>
    int main()
    {
        std::cout << std::fixed;
        double d = 123456.789;
        std::cout << d;
        return 0;
    }
    

    输出:-

    123456.789000
    

    所以我想你的问题已经解决了!!

    【讨论】:

    • 对了,printf("%f", d) 显示的是6位小数的浮点数。 std::cout 显示最大为 6 位的浮点数(包括小数点前后的数字)。我很困惑,因为我不知道这个默认精度。现在一切都清楚了……谢谢。
    • 有趣的是,我没有意识到 printf 的浮点参数实际上是双精度的。
    【解决方案3】:

    我认为这里的问题是 C++ 标准不是为了易于阅读而编写的,它是为了精确而不是重复本身而编写的。因此,如果您查看operator&lt;&lt;(double),它除了“它使用num_put”之外什么都没有说——因为这就是cout &lt;&lt; some_float_value 的实现方式。

    默认行为是 print("%g", value); 所做的[C++ 标准的 n3337 版本中的表 88 解释了 printf 和 c++ 格式的等效性]。所以如果你想做%.16g,你需要通过调用setprecision(16)来改变精度。

    【讨论】:

      猜你喜欢
      • 2017-06-02
      • 1970-01-01
      • 2023-03-14
      • 1970-01-01
      • 2018-09-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多