C 带时间计数的负数

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;

我想知道为什么我会得到负值,我尝试了多种数据类型(float、double-long-double等),但结果是。。或者它的负数或者零或者NA。这是一个检查商店中顾客的中等服务时间的函数,我只发布了问题代码的相关部分。提前付款

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 ;
}