Может кто-нибудь понять, почему эти два преобразования в unsigned long long дают разные результаты? - PullRequest
1 голос
/ 09 августа 2010
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.

Ответы [ 2 ]

1 голос
/ 09 августа 2010

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

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

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

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

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

1 голос
/ 09 августа 2010

Вы уверены, что %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

надеюсь это верно ...)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...