将100纳秒转换为毫秒混淆

时间:2016-03-28 18:13:28

标签: c++ windows time filetime

注意:这可能是一个关于数学有缺陷的问题,而不是一个问题 关于问题中描述的Windows系统调用。

我们正在使用GetSystemTimeAsFileTime() win32电话,看到我认为奇怪的结果,并正在寻找一些澄清。来自MSDN的FILETIME结构https://msdn.microsoft.com/en-us/library/windows/desktop/ms724284%28v=vs.85%29.aspx

  

包含表示100纳秒数的64位值   自1601年1月1日(UTC)以来的间隔。

根据我们对此描述的阅读,返回的值是 10e-8 间隔秒数。假设这是正确的,那么以下函数应该以毫秒为单位返回系统时间。

DWORD get_milli_time() {
    FILETIME f;
    ::GetSystemTimeAsFileTime(&f);
    __int64 nano = (__int64(f.dwHighDateTime) << 32LL)
                  + __int64(f.dwLowDateTime);
    return DWORD(nano / 10e5);
    }

然而,一个简单的单元测试显示这是不正确的,下面的代码打印&#34;失败&#34;:

DWORD start = get_milli_time();
::Sleep(5000);  // sleep for 5-seconds
DWORD end = get_milli_time();
// test for reasonable sleep variance (4.9 - 5.1 secs)
if ((end - start) < 4900 || (end - start) > 5100) {
    printf("Failed\n");
    }

根据这篇SO帖子 Getting the current time (in milliseconds) from the system clock in Windows?, 通过将我们的部门改为:

,可以获得正确的结果
return DWORD(nano / 10e3);

如果我们使用此值,我们会得到正确的结果,但我无法理解原因。

在我看来,要从 10e-8 转换为 10e-3 ,我们应该除以 10e5 。这似乎可以通过以下计算得到证实:

printf("%f\n", log10(10e-3 / 10e-8));

返回5(如我所料)。

但不知怎的,我错了 - 但如果我能看到自己出错的地方,我就会被愚弄。

1 个答案:

答案 0 :(得分:6)

你的数学确实存在缺陷,你对“工作”代码的理解也是如此。

在一秒内有10个 7 100纳秒间隔,10毫秒<1> ,毫秒。在浮点表示法中,这是1.0e410e3编写1e4是一种奇怪的方式。

“正确”(在最有效的意义上,同时保持表达力)代码将是

return DWORD(hundrednano * 1.0e-4);