1

我有这个功能

void prtduration(const FILETIME *ft_start, const FILETIME *ft_end) 
{
    double duration = (ft_end->dwHighDateTime - ft_start->dwHighDateTime) *
        (7 * 60 + 9 + 496e-3)
        + (ft_end->dwLowDateTime - ft_start->dwLowDateTime) / 1e7;
    printf("duration %.1f seconds\n", duration);
    system("pause");
}

有人可以解释以下代码部分的工作原理吗?

(ft_end->dwHighDateTime - ft_start->dwHighDateTime) *
            (7 * 60 + 9 + 496e-3)
            + (ft_end->dwLowDateTime - ft_start->dwLowDateTime) / 1e7;
4

2 回答 2

5

哇!多么令人困惑的一段代码。让我们尝试简化它:

   // Calculate the delta
   FILETIME delta;
   delta.dwHighDateTime = ft_end->dwHighDateTime - ft_start->dwHighDateTime;
   delta.dwLowDateTime = ft_end->dwLowDateTime - ft_start->dwLowDateTime;

   // Convert 100ns units to double seconds.
   double secs = delta.dwHighDateTime * 429.496 + delta.dwLowDateTime/1E7

事实上,我认为这是错误的。它应该是:

  double secs = delta.dwHighDateTime * 429.4967296 + delta.dwLowDateTime/1E7

或者更清楚:

  double secs = (delta.dwHighDateTime * 4294967296. + delta.dwLowDateTime)/10E6

正在发生的事情是高时间被乘以2**32(转换为 100ns 单位,然后除以 100ns 得到秒。

请注意,这仍然是错误的,因为计算delta错误(与原始方法相同)。如果低部分的减法下溢,则无法从高部分借入。请参阅 Microsoft 的文档:

不建议您从 FILETIME 结构中添加和减去值以获得相对时间。相反,您应该将文件时间的低位和高位部分复制到 ULARGE_INTEGER 结构,对 QuadPart 成员执行 64 位算术,并将 LowPart 和 HighPart 成员复制到 FILETIME 结构中。

或者实际上,在这种情况下,只需将 QuadPart 转换为加倍并除以。所以我们最终得到:

    ULARGE_INTEGER start,end;
    start.LowPart  = ft_start->dwLowDateTime;
    start.HighPart = ft_start->dwHighDateTime;
    end.LowPart = ft_end->dwLowDateTime;
    end.HighPart = ft_end->dwHighDateTime;

    double duration = (end.QuadPart - start.QuadPart)/1E7;

旁白:我敢打赌,从未发现借用失败的原因是代码从未被要求打印超过 7 分 9 秒的持续时间(或者如果有,没有人仔细查看结果)。

于 2016-03-16T09:06:43.883 回答
0

当 FileTime 变量改变它的值时, 7是非常近似的频率。也就是说,每 7 分钟(+-3 甚至更多)它会增加 1。然后我们将它乘以 60 以获得以秒为单位的值。

9 + 496e-3 - 时间是秒,它以某种方式处理我们正在丢失的编译(从退出开始到控制台中的输出)。

真的,这是非常糟糕的代码,我们不应该这样写。

然而,它迫使我更好地了解 FileTime 工作。

谢谢大家的回答,非常感谢。

于 2016-03-16T14:03:56.713 回答