QueryPerformanceCounter から返された時間値をミリ秒単位の double 値に変換するコードがいくつかあります。これは、カウントする方が便利だからです。
関数は次のようになります。
double timeGetExactTime() {
LARGE_INTEGER timerPerformanceCounter, timerPerformanceFrequency;
QueryPerformanceCounter(&timerPerformanceCounter);
if (QueryPerformanceFrequency(&timerPerformanceFrequency)) {
return (double)timerPerformanceCounter.QuadPart / (((double)timerPerformanceFrequency.QuadPart) / 1000.0);
}
return 0.0;
}
私が最近抱えている問題 (以前はこの問題はなかったと思いますし、コードに変更は加えられていません) は、結果があまり正確ではないということです。結果には小数は含まれませんが、1 ミリ秒よりも精度が低くなります。
デバッガーに式を入力すると、期待どおりの正確な結果が得られます。
double は 64 ビット整数の精度を保持できないことは理解していますが、現時点では、PerformanceCounter は 46 ビットしか必要としませんでした (そして、double は損失なしで 52 ビットを格納できるはずです)。分割を行う別の形式。
ここに私が得たいくつかの結果があります。プログラムはデバッグ モードでコンパイルされ、C++ オプションの浮動小数点モードはデフォルト (正確 (/fp:正確) ) に設定されました。
timerPerformanceCounter.QuadPart: 30270310439445
timerPerformanceFrequency.QuadPart: 14318180
double perfCounter = (double)timerPerformanceCounter.QuadPart;
30270310439445.000
double perfFrequency = (((double)timerPerformanceFrequency.QuadPart) / 1000.0);
14318.179687500000
double result = perfCounter / perfFrequency;
2114117248.0000000
return (double)timerPerformanceCounter.QuadPart / (((double)timerPerformanceFrequency.QuadPart) / 1000.0);
2114117248.0000000
Result with same expression in debugger:
2114117188.0396111
Result of perfTimerCount / perfTimerFreq in debugger:
2114117234.1810646
Result of 30270310439445 / 14318180 in calculator:
2114117188.0396111796331656677036
私のプログラムの結果と比較して、デバッガーのウォッチの精度が異なる理由を誰かが知っていますか?
更新: 変換と除算を行う前に、timerPerformanceCounter.QuadPart から 30270310439445 を差し引いてみましたが、現在はすべての場合で正確であるように見えます。この動作しか見られないのは、コンピューターのアップタイムが 16 日になり、値が以前よりも大きくなったためでしょうか? したがって、大きな数での除算の精度の問題であるように見えますが、ウォッチ ウィンドウで除算が依然として正しい理由はまだ説明されていません。結果に double よりも高精度の型を使用していますか?