ПРИМЕЧАНИЕ. Скорее всего, это вопрос о неправильной математике, а не вопрос о системном вызове Windows, как описано в вопросе.
Мы работаем с вызовом GetSystemTimeAsFileTime()
win32 и видим странные, на мой взгляд, результаты и нуждаемся в некоторых разъяснениях. Из MSDN в структуре FILETIME https://msdn.microsoft.com/en-us/library/windows/desktop/ms724284%28v=vs.85%29.aspx
Содержит 64-разрядное значение, представляющее количество 100-наносекундных интервалов с 1 января 1601 года (UTC).
Согласно нашему прочтению этого описания, возвращаемое значение представляет собой количество секунд интервала 10e-8. Предполагая, что это правильно, следующая функция должна возвращать системное время в миллисекундах.
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 Получение текущего время (в миллисекундах) от системных часов в Windows?, правильных результатов можно добиться, изменив наше деление на:
return DWORD(nano / 10e3);
Если мы используем это значение, мы получим правильный результат, но я не могу понять, почему.
Мне кажется, что для преобразования из 10e-8 в 10e-3 надо разделить на 10e5. Это, по-видимому, подтверждается следующим расчетом:
printf("%f\n", log10(10e-3 / 10e-8));
Который возвращает 5 (как я и ожидал).
Но почему-то я ошибаюсь — но будь я проклят, если увижу, где ошибся.
get_milli_time()
дважды с интервалом около 5 секунд и посмотреть на значения, которые он дает? - person Beta   schedule 28.03.2016