1 问题
在小白的蹩脚翻译演绎型博文《GLOG从入门到入门》中,有位热心读者提问说:在保存日志时,浮点型变量的小数位数如何设置?
首先感谢这位“嘻嘻哈哈的地球人”赏光阅读了小白这不太通顺的博客文章,并提出了一个很好的问题。
其实小白很早前就看到了这个问题,无奈小白也是一个初级程序员,而且每天的工作不能很好地完成,经常疲于奔命地应对领导的检查。所以一眼看过去不知道怎么回答这个问题,也就一直搁置在那里,没有回答。
最近又开始捯饬GLOG了,所以有了一些新的研究和分享。在此特别致以歉意并特意回复(迟到的回复)这位“嘻嘻哈哈的地球人”:这个问题至少现在小白有解了。
2 示例代码
Talk is cheap. Show me the code. 二话不说,先上代码。
#define GLOG_NO_ABBREVIATED_SEVERITIES
#include "glog/logging.h"
#include <iostream>
#include <iomanip>
#define WRITE_LOG(s) (LOG(INFO)<<s)
int main(int argc, char* argv[])
{
FLAGS_log_dir = "../Log/";
if (!google::IsGoogleLoggingInitialized())
{
google::InitGoogleLogging("Alg_Log");
}
double pi = 3.141592653;
// Method1: C语言风格的小数点控制
char testInfo[128];
sprintf_s(testInfo, "pi = %.3lf", pi);
WRITE_LOG(testInfo);
google::FlushLogFiles(google::GLOG_INFO);
// Method2: C++语言风格的输出流小数点控制
LOG(INFO) << std::fixed << std::setprecision(3) << "pi = " << pi;
google::FlushLogFiles(google::GLOG_INFO);
LOG(INFO) << std::fixed << std::setprecision(6) << "pi = " << pi;
google::FlushLogFiles(google::GLOG_INFO);
LOG(INFO) << std::fixed << std::setprecision(9) << "pi = " << pi;
google::FlushLogFiles(google::GLOG_INFO);
if (google::IsGoogleLoggingInitialized())
{
google::ShutdownGoogleLogging();
}
return 0;
}
在此例中,小白给出了一个初始的double类型的数,即圆周率 π \pi π,小白数学非常一般,只记到小数点后第9位。演示这个案例应该足够了。
以上代码的输出为:
Log file created at: 2023/02/22 21:15:19
Running on machine: DESKTOP-GC26HHT
Running duration (h:mm:ss): 0:00:00
Log line format: [IWEF]yyyymmdd hh:mm:ss.uuuuuu threadid file:line] msg
I20230222 21:15:19.565553 16452 testGlog.cpp:22] pi = 3.142
I20230222 21:15:19.569572 16452 testGlog.cpp:27] pi = 3.142
I20230222 21:15:19.569572 16452 testGlog.cpp:30] pi = 3.141593
I20230222 21:15:19.569572 16452 testGlog.cpp:33] pi = 3.141592653
接下来解释一下两种方式的小数点控制方案:
- C语言风格的格式化输出方案,也即使用
sprintf_s()
函数,将double类型(float类型也一样)的数据格式化打印成字符串,这里控制小数点的方式应该不需要小白多说; - C++语言风格的输出流小数点控制方案,也即在头文件中包含有
<iostram>
和<iomanip>
,然后通过fixed
和setprecision()
的流控制方式来控制输出字符串,小白想到这种控制方案的启示,主要来自GLOG的写入流写法,即LOG(INFO)<<s
,虽然小白没有去验证过GLOG底层的实现方式,但是猜想这种文件流或输出流的控制方式应该和C++的流输出方式是一致的。
各位热心的读者,如果你有更好的实现方式或建议,都可以打在评论区里。