Преобразование 100-наносекунд в путаницу в миллисекундах

НОТА: Это, скорее, вопрос о ошибочной математике, а не вопрос
о системном вызове 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");
}

Согласно этому посту ТАК
Получение текущего времени (в миллисекундах) от системных часов в Windows?,
правильных результатов можно достичь, изменив наше подразделение на:

return DWORD(nano / 10e3);

Если мы используем это значение, мы получим правильный результат, но я не могу понять, почему.

Мне кажется, что конвертировать из 10e-8 в 10e-3, мы должны разделить на 10e5. Казалось бы, это подтверждается следующими расчетами:

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

Который возвращает 5 (как я и ожидал).

Но почему-то я не прав — но я буду проклят, если смогу понять, где я ошибся.

0

Решение

Ваша математика действительно ошибочна, как и ваше понимание «рабочего» кода.

Есть 107 100 наносекундных интервалов в секунду, 104 в миллисекунду. В нотации с плавающей точкой это 1.0e4, 10e3 это странный способ записи 1e4,

«Правильный» (в смысле наиболее эффективный, но при этом выразительный) код

return DWORD(hundrednano * 1.0e-4);
5

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]