J'ai un code pour convertir une valeur de temps renvoyée par QueryPerformanceCounter en une valeur double en millisecondes, car il est plus pratique de compter avec.Division inexacte des doubles (Visual C++ 2008)
La fonction ressemble à ceci:
double timeGetExactTime() {
LARGE_INTEGER timerPerformanceCounter, timerPerformanceFrequency;
QueryPerformanceCounter(&timerPerformanceCounter);
if (QueryPerformanceFrequency(&timerPerformanceFrequency)) {
return (double)timerPerformanceCounter.QuadPart/(((double)timerPerformanceFrequency.QuadPart)/1000.0);
}
return 0.0;
}
Le problème que je vais avoir récemment (je ne pense pas que j'ai eu ce problème avant, et aucune modification n'a été apportée au code) est que le résultat n'est pas très précis. Le résultat ne contient pas de décimales, mais il est encore moins précis que 1 milliseconde.
Lorsque j'entre l'expression dans le débogueur, le résultat est aussi précis que je le pensais. Je comprends qu'un double ne peut pas contenir la précision d'un nombre entier de 64 bits, mais à ce moment, le PerformanceCounter ne demandait que 46 bits (et un double devrait pouvoir stocker 52 bits sans perte) En outre, il semble étrange que le débogueur utiliserait un format différent pour faire la division.
Voici quelques résultats que j'ai obtenus. Le programme a été compilé en mode débogage, flottant en mode point dans les options C++ a été défini sur la valeur par défaut (Précision (/ fp: précis))
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
Est-ce que quelqu'un sait pourquoi la précision est différente Montre le débogueur par rapport à la aboutir à mon programme?
Mise à jour: J'ai essayé de déduire 30270310439445 de timerPerformanceCounter.QuadPart avant de faire la conversion et la division, et il semble être précis dans tous les cas maintenant. Peut-être que la raison pour laquelle je ne vois que ce comportement est peut-être que le temps de disponibilité de mon ordinateur est maintenant de 16 jours, donc la valeur est plus grande que ce à quoi je suis habitué? Il semble donc que ce soit un problème de précision de division avec de grands nombres, mais cela n'explique toujours pas pourquoi la division était toujours correcte dans la fenêtre de surveillance. Utilise-t-il un type de plus haute précision que le double pour ses résultats?