簡體   English   中英

使用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一起使用 - 請參閱注釋部分。)

然后我創建一個名為ui的ConsoleUI類的實例:

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: %f\n", dt);
printf( "dt 2: %lu\n", 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

請注意,通過多次調用,最后兩行中的值稍有變化(如預期的增量時間),前兩個值不會改變 - 這看起來格式有問題。

所以,底線:調用printf直接工作,但將其傳遞給記錄器,然后調用printf不起作用...

由於您實際上無法將參數從log傳遞給printf ,因此您傳遞的是va_list - 這是正確的解決方案,但您無法將va_list傳遞給printf。

這一行:

    printf( format.c_str(), args);

打印args與格式format 假設args的類型為va_list (通常在編譯器ABI中作為void指針實現),它將不代表您在格式字符串中所期望的數據。 如果你使用

   vprintf( format.c_str(), args);

它應該工作得很好,這就是vprintf的用途。

(請注意,它與“精度損失”無關 - 它將不正確的參數類型傳遞給printf - 並且因為它是一個程序化的字符串,即使啟用警告也不會起作用)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM