我想知道为什么我得到负值我已尝试过多种数据类型(float,double long double等),但结果是..或其负数或零或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);
}
答案 0 :(得分:2)
问题是你没有将div初始化为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;
}
答案 1 :(得分:0)
你至少有三个错误,一个不明智的做法(除了使用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
的系统时钟分辨率未定义,可能无法在系统上提供微秒级分辨率。如果“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 ;
}
您将来可以很好地将编译器的警告级别设置为高,并将警告视为错误,例如GCC中的-Wall -Werror
或VC ++中的\W4 \WX
。您还应该使用源级符号调试器来查找代码中的问题。