你至少有三個錯誤,一個不明智的做法(除了使用global data就是!),和一個基本的設計缺陷:
如果你想在微秒的答案,那麼你需要0.000001不0.0000001繁殖。較少的錯誤傾向於簡單地除以1e6。
您還沒有使用過tv_sec
的會員; tv_usec
會在第二秒開始時回滾到零,所以如果開始時間在前一秒,您可能會得到一個負值 - 您當然不會得到正確的答案。
未初始化diff
。
您應該避免累積浮點運算。這是沒有必要的,並且會積累精確的錯誤,並且在這裏,long double是多餘的,因爲您只需要幾秒到幾微秒的分辨率。
即使您修復了第二個轉換問題,如果您的開始和結束恰好在午夜的任何一側,仍然存在問題。
以下修復所有,但最後的上面(解決以後)的問題:
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
系統時鐘的決議是不確定的,並且可能不提供微秒的決議在你的系統上。如果「做一團亂七八糟」所需的時間少於時鐘分辨率,您將得到零或時鐘分辨率的答案。
您可確定由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或\W4 \WX
在VC++爲例。您還應該使用源代碼級符號調試器來查找代碼中的問題。
對'getMedia'的調用應該是'getMedium'還是一個不同的函數?「diff」累加表達式中的圓括號不匹配,所以這不是真正的代碼 - 我們可以解決您無法解決的問題;如果我們能看到真正的代碼,那麼就不會有問題! – Clifford
字段'tv_usec'可能是'long'。 '0.0000001'當然是一個'雙'。所以'diff + = ...'的右邊只能用'double'精確數學來完成。然而,代碼以「long double」累加。考慮「0.0000001L」的統一精度。 – chux