[英]Negative numbers with time count
我想知道為什么我得到負值我已嘗試過多種數據類型(浮點數,雙倍長雙等)但結果是..或其負數或零或NA。 這是一個檢查商店中客戶的中等服務時間的功能,我只發布了問題代碼的相關部分。 Ty提前
struct timeval timecount[MAX_COSTUMERS+1][2];
long double getMedium(struct timeval x[][2]){
long double diff;
int i;
for(i=1;i<k.clientID;i++){
diff+= ((x[i][1].tv_usec )*0.0000001 - (x[i][0].tv_usec)*0.0000001) ) ;
}
return diff;
}
void AFUNCTION(){ // Called a bunch of times
k.clientID++;
gettimeofday(&timecount[k.clientID][0], NULL);
// DO A BUNCH OF STUFF
gettimeofday(&timecount[k.clientID][1], NULL);
}
void main ( ) {
long double aux;
aux=getMedia(timecount);
printf("%LG \n",aux);
}
問題是你不要將dif init初始化為0.那里有垃圾數據......
double getMedium(struct timeval x[][2]){
double diff =0;
int i;
for(i=1;i<k.clientID;i++){
diff+= ((x[i][1].tv_usec )*0.0000001 - (x[i][0].tv_usec)*0.0000001) ) ;
}
return diff;
}
你至少有三個錯誤,一個不明智的做法(除了使用全球數據 !),還有一個基本的設計缺陷:
如果你想要一個以微秒為單位的答案,那么你需要乘以0.000001而不是0.0000001。 不易出錯,簡單地除以1e6。
你還沒有使用過tv_sec
成員; tv_usec
將在第二個開始時翻轉為零,所以如果開始時間是在前一秒,你可能得到一個負值 - 你當然得不到正確的答案。
無法初始化diff
。
您應該避免使用浮點運算進行累積。 這是不必要的,並且會累積精度誤差,並且長雙倍是多余的,因為您只需要幾秒到微秒的分辨率。
即使您修復了第二個翻車問題,如果您的開始和結束恰好是午夜的一側,問題仍然存在。
以下修復了除上述最后一個問題之外的所有問題(以后的解決方案):
double getMedium( struct timeval x[][2] )
{
unsigned long long diff = 0 ;
int i ;
for( i = 1; i < k.clientID; i++ )
{
unsigned long long start_usec = x[i][0].tv_usec * 1000000ULL + x[i][0].tv_usec ;
unsigned long long end_usec = x[i][1].tv_usec * 1000000ULL + x[i][1].tv_usec ;
diff += end_usec - start_usec ;
}
return diff / 1.0e6 ;
}
用於gettimeofday
的系統時鍾的分辨率未定義,並且可能無法在系統上提供微秒級分辨率。 如果“DO A BUNCH OF STUFF”花費較少的時間分辨率,您將獲得零或時鍾分辨率的答案。
您可以通過以下方式確定gettimeofday
使用的時鍾分辨率:
#include <stdio.h>
#include <sys/time.h>
int main()
{
struct timeval t ;
unsigned long long start_usec ;
unsigned long long end_usec ;
gettimeofday( &t, 0 ) ;
start_usec = t.tv_sec * 1000000ULL + t.tv_usec ;
do
{
gettimeofday( &t, 0 ) ;
end_usec = t.tv_sec * 1000000ULL + t.tv_usec ;
} while( start_usec == end_usec ) ;
printf( "Clock resolution = %u microsecond(s)", end_usec - start_usec ) ;
return 0 ;
}
您當然可以通過使用標准庫clock()
函數來顯着簡化此代碼,該函數幾乎肯定會具有與gettimeofday()
相同的分辨率(檢查CLOCKS_PER_SEC的定義以確定),但沒有任何相關的第二個問題或白天環繞。
#include <time.h>
double getMedium( struct timeval x[][2] )
{
time_t diff = 0 ;
int i ;
for( i = 1; i < k.clientID; i++ )
{
time_t start_time = clock() ;
time_t end_time = clock() ;
diff += end_time - start_time ;
}
return (diff * CLOCKS_PER_SEC) / 1.0e6 ;
}
您將來可以很好地將編譯器的警告級別設置為高,並將警告視為錯誤, -Wall -Werror
,GCC中的-Wall -Werror
或VC ++中的\\W4 \\WX
。 您還應該使用源級符號調試器來查找代碼中的問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.