Может кто-нибудь расшифровать, почему эти два преобразования в unsigned long long дают разные результаты?

LARGE_INTEGER lpPerformanceCount, lpFrequency;

QueryPerformanceCounter(&lpPerformanceCount);
QueryPerformanceFrequency(&lpFrequency);

(Count.QuadPart - длинная длинная строка, показывающая количество процессоров)

(Freq.QuadPart - длинная длинная частота отображения количества для секунда)

Попытка печати микросекунд в режиме реального времени.

стабильный вывод:

printf("%llu\n", ((long double)lpPerformanceCount.QuadPart/ lpFrequency.QuadPart) * 1000000);

ошибочный вывод: (результат скачет некогерентно вперед и назад, даже если это на первый взгляд вменяемое)

printf("%llu\n", 1000000 * (lpPerformanceCount.QuadPart / lpFrequency.QuadPart) + (lpPerformanceCount.QuadPart % lpFrequency.QuadPart));

РЕДАКТИРОВАТЬ: printf нужно еще ( преобразование unsigned long long) на входе, исходный код выполнял это с помощью возвращаемого значения func.

1
задан j riv 10 August 2010 в 10:15
поделиться

2 ответа

Вы уверены, что %llu печатает разумное двойное значение?

lpPerformanceCount.QuadPart / lpFrequency.QuadPart дает вам время, округленное до полных секунд.

lpPerformanceCount.QuadPart % lpFrequency.QuadPart дает счетчик тиков (количество тиков с последней полной секунды).

Прибавив счетчик к времени, вы получите... как бы это сказать повежливее... дерьмо.

Я всегда использую двойную арифметику, гораздо меньше хлопот. Однако, если вы настаиваете на том, что код не на FPU, вы можете использовать:

count.QuadPart*1000000 / (freq.QuadPart*1000000)

что приведет к более быстрому переполнению (хотя это не является практической проблемой, как я полагаю). Исправим это для целочисленной арифметики:

count.QuadPart / freq.QuadPart 
+ (count.QuadPart % freq.QuadPart) * 1000000 / freq.QuadPart

надеюсь, что это правильно...)

1
ответ дан 2 September 2019 в 22:20
поделиться

Да. IIUC, это должно быть что-то вроде:

1000000 * (lpPerformanceCount.QuadPart / lpFrequency.QuadPart) + 
(lpPerformanceCount.QuadPart % lpFrequency.QuadPart) * 1000000 / lpFrequency.QuadPart

или, может быть,

(lpPerformanceCount.QuadPart / (lpFrequency.QuadPart / 1000000) )

Первый будет переполнен, если lpFreuency.QuadPart высокий; второй будет неточным или даже переполненным, если lpFrequency.QuadPart низкое.

1
ответ дан 2 September 2019 в 22:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: