2013-12-11 5 views
0

Интересно, почему im получает отрицательные значения? Ив пытался использовать несколько типов данных (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

Должен ли вызов 'getMedia' быть' getMedium' или это другая функция?Скобки не совпадают в выражении накопления 'diff', поэтому это не настоящий код, мы могли бы решить проблемы, которые вы наделаете, если мы сможем увидеть реальный код! – Clifford

+0

Поле 'tv_usec', скорее всего,' long'. '0,0000001' - это, безусловно,' double'. Таким образом, правая часть 'diff + = ...' может быть выполнена только с математической точностью «double». Однако код накапливается с 'long double'. Учитывайте '0,0000001L' для равномерной точности. – chux

ответ

0

У вас есть по крайней мере три ошибки, один опрометчивый практика (за исключением использования 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++, например. Вы также должны использовать символический отладчик исходного уровня, чтобы найти проблемы в своем коде.

2

Проблема заключается не initilize диф 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; 
} 
+0

все еще отрицательный: ( – Noize

+0

@Нойти это на самом деле не стоит даже компилировать, есть лишний) на линии дифференциала. –

+1

@Noize есть что-нибудь, препятствующее вам делать '(x [i] [1] .tv_usec - x [i] [0] .tv_usec) * 0.0000001'? Математически они одинаковы, но с вычислительной точки зрения несколько более эффективны. Кроме того, 'printf' или two будут очень quiclky сказать вам, где проблема, если вы думаете, что' diff' вычисляется неправильно ... – nonsensickle

Смежные вопросы