如何避免警告C4244:从ULONGLONG'转换双重'可能会丢失数据

时间:2017-11-17 07:24:52

标签: c++ c winapi visual-c++ compiler-warnings

我正在使用Win32 x64环境

请点击下面的链接

我已从此链接中找到答案Collecting CPU Usage of a Process

Windows 条件的第一个答案下,您可以看到如下代码段:

double getCurrentValue(){
    FILETIME ftime, fsys, fuser;
    ULARGE_INTEGER now, sys, user;
    double percent;

    GetSystemTimeAsFileTime(&ftime);
    memcpy(&now, &ftime, sizeof(FILETIME));

    GetProcessTimes(self, &ftime, &ftime, &fsys, &fuser);
    memcpy(&sys, &fsys, sizeof(FILETIME));
    memcpy(&user, &fuser, sizeof(FILETIME));
    percent = (sys.QuadPart - lastSysCPU.QuadPart) +
        (user.QuadPart - lastUserCPU.QuadPart);
    percent /= (now.QuadPart - lastCPU.QuadPart);
    percent /= numProcessors;
    lastCPU = now;
    lastUserCPU = user;
    lastSysCPU = sys;

    return percent * 100;
}
//--------------------------- FOCUS -----------------------------//
    percent = (sys.QuadPart - lastSysCPU.QuadPart) +(user.QuadPart - lastUserCPU.QuadPart); // ---(1)
    percent /= (now.QuadPart - lastCPU.QuadPart); // ---(2)
    percent /= numProcessors; // --- (3)

如行(1)将ULONGLONG(无符号long long)分配给double给编译器warning C4244: conversion from 'ULONGLONG' to 'double', possible loss of data

  • 因此@Line#(1),(2)& (3)我们如何才能保证double precent数据的价值?

(由于Ulonglong 64位积分数据转换为64位浮点数据)

  • 有时,此precent值的值高于 100.00 ,时间戳为CPU使用率

1 个答案:

答案 0 :(得分:1)

假设您在短时间内调用getCurrentValue函数,您可以安全地将值转换为double。您还可以通过以年为单位的呼叫来检查极端情况。

ULONGLONG used = (sys.QuadPart - lastSysCPU.QuadPart) + (user.QuadPart - lastUserCPU.QuadPart);
ULONGLONG elapsed = (now.QuadPart - lastCPU.QuadPart);
if ( elapsed == 0 )
{
    // Now it is imposible, but it could be problem in future :)
    // Do something sane here. For example restart calculation.
}
else
{
    double percent = ( (double)used / (double)elapsed ) / numProcessors * 100.0;
    // Clamp value for rounding errors in our or system code.
    if ( percent > 100.0 )
        percent = 100.0;

    if ( elapsed >= ( 1ull << 53 ) || used >= ( 1ull << 53 ) )
    {
         // Set some flag that result could be not precise.
         // For 'elapsed' this needs 28 years.
         // 'used' could kick earlier: 28/num_processors years.
         // But if you realy need only 4 or 5 digits you can
         // ignore this case.
    }
}