将100纳秒的混乱转换为毫秒的混乱

Convert 100-nanoseconds to millisecond confusion

本文关键字:混乱 转换      更新时间:2023-10-16

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

我们正在处理GetSystemTimeAsFileTime() win32调用,看到了我认为奇怪的结果,并希望得到一些澄清。来自FILETIME结构上的MSDNhttps://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);
    }

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

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("Failedn");
    }

根据该SO帖子从Windows中的系统时钟获取当前时间(以毫秒为单位)?,正确的结果可以通过将我们的部门改为:来实现

return DWORD(nano / 10e3);

如果我们使用这个值,我们会得到正确的结果,但我不明白为什么。

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

printf("%fn", log10(10e-3 / 10e-8));

它返回5(正如我所期望的)。

但不知怎么的,我错了——但如果我能看到我哪里错了,我会很生气的。

你的数学确实有缺陷,你对"工作"代码的理解也有缺陷。

一秒钟内有107100纳秒的间隔,一毫秒内有104的间隔。在浮点表示法中,这是1.0e410e3是一种奇怪的1e4书写方式。

"正确的"(从最有效的意义上讲,同时保持表达能力)代码将是

return DWORD(hundrednano * 1.0e-4);