使用va_list和printf传递参数时的精度损失
Precision loss when passing arguments using va_list and printf
我有一个日志记录函数,它是这样工作的:
// public function:
void ConsoleUI::log(const std::string& format, ...) {
va_list args;
va_start(args, format);
log(format, args);
va_end(args);
}
// overloaded private function:
void ConsoleUI::log(const std::string& format, va_list args) {
//wprintw( outWin, format.c_str(), args);
//wprintw( outWin, "n");
printf( format.c_str(), args);
printf( "n");
}
(旁注:这应该与普通的printf完全相同,所以在这种状态下它是相当无用的。这是因为这是一个最小可行的例子。最后,这应该适用于ncurses(参见注释部分)
然后创建一个ConsoleUI类的实例,称为ui:
ConsoleUI ui;
后来我用它来记录东西,更准确地说,以微秒为单位的time_duration:
now = boost::posix_time::microsec_clock::local_time();
boost::posix_time::time_duration delta = now - lastTime;
double dt = 1e-6*(double)delta.total_microseconds();
lastTime = now;
ui.log( "logged dt: %f", dt );
ui.log( "logged dt 2: %lu", delta.total_microseconds());
printf( "dt: %fn", dt);
printf( "dt 2: %lun", delta.total_microseconds());
得到的输出:
logged dt: 0.000000
logged dt 2: 140736013247624
dt: 0.018739
dt 2: 18739
我所期望的:
logged dt: 0.018739
logged dt 2: 18739
dt: 0.018739
dt 2: 18739
请注意,在多次调用this之后,最后两行中的值会有轻微的变化(这是预期的增量时间),而前两个值不会改变——这看起来像是格式有问题。
所以,底线:直接调用printf工作,但将它传递给logger然后调用printf不起作用…
由于您实际上不能将参数从log
传递到printf
,因此您传递的是va_list
-这是正确的解决方案,但您不能将va_list
传递到printf。
:
printf( format.c_str(), args);
以format
的格式打印args
。考虑到args
是va_list
类型(通常在编译器ABI中作为一个void指针实现),它将不代表您期望在格式字符串中的数据。如果使用
vprintf( format.c_str(), args);
它应该工作得很好,这就是vprintf
的作用。
(请注意,这与"精度损失"无关-它将不正确的参数类型传递给printf -并且由于它是一个编程制定的字符串,因此即使启用警告也无法工作)。
相关文章:
- 转换函数,将 std::数组的双精度作为参数或双精度作为参数单独转换
- 为什么在传递长整型时调用具有两个双精度类型的参数的重载函数?
- 将不同类型的模板参数包提取到双精度向量中会产生警告
- C++双精度作为模板参数的解决方法
- 一元'*'的类型参数无效(有双精度)
- 当将变量作为函数参数传递时,由于隐式铸造而导致的精度丧失
- 错误:类型"类特征::张量<双精度,3>"参数提供给"删除",预期指针
- 使用整数模板参数创建编译时双精度
- 如何替换具有双精度类型的模板参数
- 如何使C++函数使用双精度参数或无参数执行
- 具有双精度参数的数组
- 试图将数组作为参数传递,得到双精度[4]到双精度转换错误
- 如何设置adDecimal 参数的精度以避免"invalid precision"错误?
- 如何为通过地址传递参数的Windows API调用编写测试双精度
- 以双精度数除以双精度数来获得循环中的余数和char参数不起作用
- 拆分64位值以适应双精度参数类型
- 为零填充宽度和精度与要打印的整型参数相同
- 使用va_list和printf传递参数时的精度损失
- 包含两个双精度的类是 std::complex 参数的有效替代品<double>吗?
- 不带参数地设置精度