Why is this floating point addition result not correct?

114 views Asked by At

I am trying to calculate the time in buffer in microseconds.

But I don't understand why the floating-point operation result of my code is not correct.

float time, sec; 
int h, m;
sscanf(16:41:48.757996, "%d:%d:%f", &h, &m, &sec);
printf("buffer %s\n",buffer);
printf("hour %d\n",h);
printf("minute %d\n",m);
printf("seconde %f\n",sec);
time=3600*h+60*m;+sec;
printf("%f\n",time);

When I execute this code, I get the following result:

buffer 16:41:48.757996
heure 16
minute 41
seconde 48.757996
60108.757812

But I am expecting:

buffer 16:41:48.757996
heure 16
minute 41
seconde 48.757996
60108.757996

The result of the floating-point operation is not correct.

4

There are 4 answers

1
Amol Saindane On BEST ANSWER

According to IEEE 754 encoding, many numbers will have small changes to allow them to be stored.Also, the number of significant digits can change slightly since it is a binary representation, not a decimal one.

Single precision (float) gives you 23 bits of significand, 8 bits of exponent, and 1 sign bit.

Double precision (double) gives you 52 bits of significand, 11 bits of exponent, and 1 sign bit.

Following code snippet will work for you

#include<stdio.h>
#include <stdlib.h>

int main()
{
    double time, sec; // changed to double
    double h, m;
    sscanf("16:41:48.757996", "%lf:%lf:%lf", &h, &m, &sec);
    printf("hour %lf\n",h);
    printf("minute %lf\n",m);
    printf("seconde %lf\n",sec);
    time=3600*h+60*m+sec;
    printf("%lf\n",time);
}
5
haccks On

Change float to double if want more precision

double time, sec;   

and use %lf in sscanf. You will get the desired result.

Live Demo

0
flat1991 On

The calculation is good with doubles!

double time, sec;
sscanf(buffer, "%d:%d:%lf", &h, &m, &sec);
printf("buffer %s\n",buffer);
printf("heure %d\n",h);
printf("minute %d\n",m);
printf("seconde %f\n",sec);

P.TempsEmission=3600*h+60*m+sec;    
printf("%lf\n",P.TempsEmission);
5
Natasha Dutta On

I think, you have a small typo in your code. Change

time=3600*h+60*m;+sec;

to

time=3600*h+60*m+sec;  // remove ; from the apparent middle of the statement
                ^^

Otherwise, the sec value is becoming essentially useless.

That said, always check for the return value of sscanf() to ensure success.


EDIT:

As others have pointed out, the main reason behind losing the precision is due to the use of float type. It is nicely explained in this answer that, changing the variable type to double will increase the precision and you'll get a fine-grained result, as you've expected.