将 100 纳秒转换为毫秒混淆
Convert 100-nanoseconds to millisecond confusion
注意:这可能是一个关于有缺陷的数学的问题,而不是一个问题
关于问题中描述的 windows 系统调用。
我们正在处理 GetSystemTimeAsFileTime()
win32 调用,看到了我认为奇怪的结果,正在寻求一些说明。来自 MSDN 上的 FILETIME 结构 https://msdn.microsoft.com/en-us/library/windows/desktop/ms724284%28v=vs.85%29.aspx
Contains a 64-bit value representing the number of 100-nanosecond
intervals since January 1, 1601 (UTC).
根据我们阅读此描述,值returned 是10e-8 间隔秒数。假设这是正确的,那么下面的函数应该 return 以毫秒为单位的系统时间。
DWORD get_milli_time() {
FILETIME f;
::GetSystemTimeAsFileTime(&f);
__int64 nano = (__int64(f.dwHighDateTime) << 32LL)
+ __int64(f.dwLowDateTime);
return DWORD(nano / 10e5);
}
然而,一个简单的单元测试表明这是不正确的,下面的代码打印 "Failed":
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 post
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));
其中 returns 5(如我所料)。
但不知何故我错了 -- 但如果我能看到我哪里出错了,我会很高兴的。
你的数学确实有问题,你对"working"代码的理解也是如此。
一秒有 107 个 100 纳秒间隔,一毫秒有 104 个。在浮点表示法中,这是 1.0e4
。 10e3
是一种奇怪的写法 1e4
.
"right"(从最有效的意义上说,同时保持表现力)代码将是
return DWORD(hundrednano * 1.0e-4);
注意:这可能是一个关于有缺陷的数学的问题,而不是一个问题 关于问题中描述的 windows 系统调用。
我们正在处理 GetSystemTimeAsFileTime()
win32 调用,看到了我认为奇怪的结果,正在寻求一些说明。来自 MSDN 上的 FILETIME 结构 https://msdn.microsoft.com/en-us/library/windows/desktop/ms724284%28v=vs.85%29.aspx
Contains a 64-bit value representing the number of 100-nanosecond intervals since January 1, 1601 (UTC).
根据我们阅读此描述,值returned 是10e-8 间隔秒数。假设这是正确的,那么下面的函数应该 return 以毫秒为单位的系统时间。
DWORD get_milli_time() {
FILETIME f;
::GetSystemTimeAsFileTime(&f);
__int64 nano = (__int64(f.dwHighDateTime) << 32LL)
+ __int64(f.dwLowDateTime);
return DWORD(nano / 10e5);
}
然而,一个简单的单元测试表明这是不正确的,下面的代码打印 "Failed":
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 post 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));
其中 returns 5(如我所料)。
但不知何故我错了 -- 但如果我能看到我哪里出错了,我会很高兴的。
你的数学确实有问题,你对"working"代码的理解也是如此。
一秒有 107 个 100 纳秒间隔,一毫秒有 104 个。在浮点表示法中,这是 1.0e4
。 10e3
是一种奇怪的写法 1e4
.
"right"(从最有效的意义上说,同时保持表现力)代码将是
return DWORD(hundrednano * 1.0e-4);