У вас есть по крайней мере три ошибки, один опрометчивый практика (за исключением использования global data, что это!), и один фундаментальный недостаток дизайна:
Если вы хотите получить ответ в микросекундах, то вам нужно умножить на 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 или \W4 \WX
в VC++, например. Вы также должны использовать символический отладчик исходного уровня, чтобы найти проблемы в своем коде.
Должен ли вызов 'getMedia' быть' getMedium' или это другая функция?Скобки не совпадают в выражении накопления 'diff', поэтому это не настоящий код, мы могли бы решить проблемы, которые вы наделаете, если мы сможем увидеть реальный код! – Clifford
Поле 'tv_usec', скорее всего,' long'. '0,0000001' - это, безусловно,' double'. Таким образом, правая часть 'diff + = ...' может быть выполнена только с математической точностью «double». Однако код накапливается с 'long double'. Учитывайте '0,0000001L' для равномерной точности. – chux