2011-04-26 5 views
0

Dans le code suivant, une chose étrange se produit. La fonction get_time_in_seconds(), une fonction personnalisée que j'ai construite et testée de manière indépendante, fonctionne correctement lorsqu'elle est appelée directement depuis l'instruction printf longue. Cependant, il ne stocke pas la valeur attendue lorsque je l'assigne à la variable curr_time2. Tout devine pourquoi?Quel est le problème avec ce code?

while (1) 
{ 
    count++; 
    bytes_read = recvfrom(sock,recv_data,1024,0,(struct sockaddr *)&client_addr, (socklen_t*)&addr_len); 
    recv_data[bytes_read] = '\0'; 
    strcpy(buff,inet_ntoa(client_addr.sin_addr)); 
    printf("\nAt %lf (%s , %d, Num : %d) said : ",get_time_in_seconds(),buff,ntohs(client_addr.sin_port),get_id(buff)); 
    printf("%s", recv_data); 
    curr_time2=get_time_in_seconds(); 
    printf("%lf\n",curr_time2); 
//  data.nodeid=get_id(buff); 
//  data.time = curr_time2; 
    //printf("%f,%f\n",data.time,curr_time2); 
    store_packetdata(&data); 
    fflush(stdout); 
} 

sortie de l'échantillon:

A 1.303.829.191,827888 (10.22.6.162, 35355, Nb: 1) dit: 505 1303829248,000000

A 1.303.829.196,827893 (10.22.6.162, 35355, Nb : 1) dit: 506 1303829248.000000

Au 1303829201.827898 (10.22.6.162, 35355, Nb: 1) dit: 507 1303829248,000000

A 1.303.829.206,827903 (10.22.6.162, 35355, Nb: 1) dit: 508 1303829248,000000

A 1.303.829.211,827908 (10.22.6.162, 35355, Nb : 1) dit: 509 1303829248,000000

A 1.303.829.216,827913 (10.22.6.162, 35355, Nb: 1) dit: 510 1303829248,000000

A 1.303.829.221,827918 (10.22.6.162, 35355, Nb: 1) dit: 511 1303829248,000000

A 1.303.829.226,827923 (10.22.6.162, 35355, Nb: 1) dit: 512 1303829248,000000

A 1303829231,827928 (10.22.6.162, 35355, Nb: 1) a indiqué: 513 1303829248,000000

A 1.303.829.236,827933 (10.22.6.162, 35355, Nb: 1) dit: 514 1303829248,000000

À 1.303.829.241,827938 (10.22.6.162, 35355, Num: 1) dit: 515 1303829248,000000

EDIT: J'ai maintenant résolu le problème. Initialement à la fois curr_time2 et le type de retour de get_time_in_sconds() étaient en float. Quand j'ai converti les deux pour doubler le code a commencé à travailler. Cependant, ce que je veux savoir, c'est pourquoi printf() était précis tandis que curr_time2 n'enregistrait qu'une approximation de la valeur.

Nouvelles déclarations (changer le double pour flotter pour les anciennes).

double get_time_in_seconds() 
{ 
    gettimeofday(&tv, NULL); 
    double retval= (double)tv.tv_sec + ((double)tv.tv_sec)/1000000; 
    return retval; 
} 
    static double curr_time2=0.0; 
+1

@ apoorv020: pouvez-vous poster votre fonction get_time_in_second et la déclaration de curr_time2? – Heisenbug

+0

Quel type est 'curr_time2'? – pmg

+0

de quel type est curr_time2? Quel type de données renvoie get_time_in_seconds()? – Axel

Répondre

2

Sans connaître le type de curr_time2 je ne peux que deviner, mais il semble être déclarée entier et non flotter.

Si ce n'était pas le cas s'il vous plaît poster plus de code (les déclarations de fonctions et d'arguments), car pour le moment je ne peux pas faire plus alors cette conjecture.

1

après la modification

> pourquoi printf() est une impression précise

La fonction printf() est une fonction variadique.
Arguments "souffrent" conversions par défaut: fondamentalement char et short à int; float à double.

Dans votre code

printf("%lf", float_value); 

le float_value est automatiquement converties en double et la spécification de conversion %lf est traité de la même que %f dans C99 ("%lf" est une erreur C89) qui attend une valeur double.

+0

Mais la fonction ne devrait-elle pas renvoyer une valeur flottante, perdant ainsi sa précision avant que printf utilise la valeur? – apoorv020

+0

Je suppose que cela devrait perdre de la précision. Cependant, je n'ai pas trouvé de passage pertinent dans la norme. * Sur un petit fichier de test, gcc (et [compilateur ideone] (http://ideone.com/8hihD)) se sont comportés comme prévu, perdant de la précision *. – pmg

1

La plupart des compilateurs C ne transmettent pas réellement les valeurs float en tant que paramètres ou les renvoient des fonctions - ils seront convertis en double pour cela. Donc, lorsque vous passiez directement la valeur de retour de get_time_in_seconds() à printf, cela a été fait en double précision. Cependant, lorsque vous l'avez stocké dans la variable floatcurr_time2, il le convertit en simple précision pour le magasin et revient en double précision pour passer à printf.

Notez que le comportement est autorisée au-dessus de la spécification, mais pas le comportement requis - le compilateur C est toujours autorisé (par la spécification) d'utiliser une précision supplémentaire pour les valeurs intermédiaires tels que les paramètres de fonction et de retour des valeurs