C 带时间计数的负数
我想知道为什么我会得到负值,我尝试了多种数据类型(float、double-long-double等),但结果是。。或者它的负数或者零或者NA。这是一个检查商店中顾客的中等服务时间的函数,我只发布了问题代码的相关部分。提前付款C 带时间计数的负数,c,shell,unix,time,C,Shell,Unix,Time,我想知道为什么我会得到负值,我尝试了多种数据类型(float、double-long-double等),但结果是。。或者它的负数或者零或者NA。这是一个检查商店中顾客的中等服务时间的函数,我只发布了问题代码的相关部分。提前付款 struct timeval timecount[MAX_COSTUMERS+1][2]; long double getMedium(struct timeval x[][2]){ long double diff; int i;
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);
}
struct timeval timecount[MAX_customers+1][2];
长双getMedium(结构时间值x[][2]){
长双差;
int i;
对于(i=1;i而言,问题在于没有将dif初始化为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;
}
double-getmedia(struct-timeval x[][2]){
双差=0;
int i;
对于(i=1;i您至少有三个错误,一个不明智的做法(除了使用is!),以及一个基本的设计缺陷:
- 如果你想在微秒内得到答案,那么你需要乘以0.000001,而不是0.0000001。只需除以1e6就可以减少错误
- 您没有使用
tv_sec
成员;tv_usec
将在第二秒开始时滚动到零,因此如果开始时间在前一秒,您可能会得到负值-您肯定不会得到正确的答案
- 未能初始化
diff
- 您应该避免使用浮点运算进行累加。这是不必要的,并且会累加精度错误,而长双精度在这里是多余的,因为您只需要秒到微秒的分辨率
- 即使您解决了第二个滚动问题,但如果您的开始和结束时间恰好在午夜的两侧,则问题仍然存在
以下修复了除最后一个问题外的所有问题(稍后解决方案):
当然,您可以通过使用标准库clock()
函数大大简化此代码,该函数几乎肯定具有与gettimeofday()
相同的分辨率(请检查每秒时钟的定义),但没有第二天或第二天环绕的相关问题
#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 ;
}
#包括
双getMedium(结构时间值x[][2])
{
时间差=0;
int i;
对于(i=1;i
将来,您最好将编译器上的警告级别设置为高级别,并将警告视为错误,例如GCC中的-Wall-Werror
,或VC++中的\W4\WX
。您还应该使用源代码级符号调试器来查找代码中的问题。@Noize这实际上不应该编译,因为存在extra)在差异线上。@Noize是否有任何东西阻止您执行(x[i][1]。tv\u usec-x[i][0]。tv\u usec)*0.0000001
?数学上它们是一样的,但计算效率稍高。此外,如果你认为diff
计算错误,一两个printf
会很快地告诉你问题出在哪里…@荒谬:更好的做法是在循环外累加并除以1.0e6。0.0000001是不正确的n在任何情况下,如果需要在几秒钟内得到结果-0太多了!使用调试器要比printf
调试好。对getMedia
的调用应该是getMedia
还是另一个函数?括号在diff
累积表达式中不匹配,因此这不是真正的代码-我们如果我们能看到真正的代码,可能是在解决你没有的问题!字段tv\u usec
很可能是long
0.0000001
肯定是double
。因此diff+=…
的右侧只能用double
精确数学来完成。然而,代码是用long double
累积的。考虑<代码> 0 000000 1L<代码>以获得一致的精度。
#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 ;
}
#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 ;
}