C++ 格式化输出浮点数

在性能分析或日志记录中,我们经常需要打印时间戳并比较它们的差异。

但如果我们不注意输出格式,可能会遇到一点小问题:

假设下面两个时间戳 t1t2,分别表示某个操作的开始和结束时间。

我们想看看它们的差异,因此将它们打印出来:

#include <iostream>

int main() {
    
    
    double t1 = 1633036800.123456;  // 开始时间
    double t2 = 1633036800.123789;  // 结束时间

    std::cout << "Start time: " << t1 << std::endl;
    std::cout << "End time:   " << t2 << std::endl;

    return 0;
}

输出结果

Start time: 1.63304e+09
End time:   1.63304e+09

问题是显而易见的,这俩长得一样!

这个问题源于 C++ 默认的浮点数输出行为:当数值的绝对值非常大或非常小时,C++ 会使用科学计数法来显示。

接下来,我们将深入探讨 C++ 的浮点数输出规则,并逐步解决这个问题。


默认的浮点数输出行为

在 C++ 中,浮点数的默认输出格式会根据数值的大小自动选择固定小数格式科学计数法格式

具体规则如下:

当数值的绝对值大约在 [1e-4, 1e6] 范围内时,默认使用固定小数格式,超出这个范围使用科学计数法格式。

扫描二维码关注公众号,回复: 17616945 查看本文章

示例

#include <iostream>
#include <iomanip>

int main() {
    
    
    // 在范围内
    double a = 0.0001;    
    double b = 999999;   

    // 超出范围
    double c = 0.00009;   
    double d = 1000000;  

    std::cout << "a : " << a << std::endl;  // 0.0001
    std::cout << "b : " << b << std::endl;  // 999999
    std::cout << "c : " << c << std::endl;  // 9e-05
    std::cout << "d : " << d << std::endl;  // 1e+06
}

输出结果

a : 0.0001
b : 999999
c : 9e-05
d : 1e+06

使用 std::fixed 固定小数格式

std::fixed 用于强制浮点数以固定小数格式输出。

它的作用是让浮点数始终以小数形式显示,而不是科学计数法。

语法

std::cout << std::fixed << value;

示例

#include <iostream>

int main() {
    
    
    double largeNumber = 1234567.89;

    // 默认输出(科学计数法)
    std::cout << "Default: " << largeNumber << std::endl;

    // 使用 std::fixed 固定小数格式
    std::cout << "Fixed: " << std::fixed << largeNumber << std::endl;

    return 0;
}

输出结果

Default: 1.23457e+06
Fixed: 1234567.890000

使用 std::setprecision 控制精度

std::setprecision 用于设置浮点数输出的精度。它的行为取决于是否与 std::fixedstd::scientific 结合使用:

  • 默认情况std::setprecision(n) 设置总的有效数字位数。
  • std::fixed 结合std::setprecision(n) 设置小数点后的位数。

示例

#include <iostream>
#include <iomanip>  // 需要包含此头文件

int main() {
    
    
    double pi = 3.14159265358979323846;

    // 默认行为
    std::cout << "Default (5 digits): " << std::setprecision(5) << pi << std::endl;

    // 与 std::fixed 结合
    std::cout << "Fixed (5 digits):   " << std::fixed << std::setprecision(5) << pi << std::endl;

    return 0;
}

输出结果

Default (5 digits): 3.1416
Fixed (5 digits):   3.14159

解决时间戳的格式化输出

现在,让我们回到开头的时间戳问题,我们可以使用 std::fixedstd::setprecision 将时间戳和差异值以固定小数格式输出,确保数值直观可读。

#include <iostream>
#include <iomanip>  // 需要包含此头文件

int main() {
    
    
    double t1 = 1633036800.123456;  // 开始时间
    double t2 = 1633036800.123789;  // 结束时间

    std::cout << std::fixed << std::setprecision(6);  // 设置固定小数格式,保留6位小数
    std::cout << "Start time: " << t1 << std::endl;
    std::cout << "End time:   " << t2 << std::endl;

    return 0;
}

输出结果

Start time: 1633036800.123456
End time:   1633036800.123789

修改后,我们可以看到,时间戳以固定小数格式输出,清晰展示了具体的时间值。


总结

  • 默认行为:C++ 根据数值大小自动选择固定小数格式或科学计数法格式。
  • std::fixed:强制使用固定小数格式。
  • std::setprecision:设置浮点数的输出精度。
  • 结合使用std::fixedstd::setprecision 可以精确控制小数点后的位数。

希望本文对你有所帮助!
最后,欢迎大家关注我的微信公众号《嵌入式3分钟》,一起学习嵌入式!
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/TIME_LEAF/article/details/145935895
今日推荐