简体   繁体   English

为什么此浮点加法结果不正确?

[英]Why is this floating point addition result not correct?

I am trying to calculate the time in buffer in microseconds. 我正在尝试以微秒为单位计算buffer中的时间。

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. 浮点运算的结果不正确。

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. 否则, sec值变得基本上是无用的。

That said, always check for the return value of sscanf() to ensure success. 也就是说,请始终检查sscanf()的返回值以确保成功。


EDIT: 编辑:

As others have pointed out, the main reason behind losing the precision is due to the use of float type. 正如其他人指出的那样,失去精度的主要原因是使用float类型。 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. 此答案中很好地解释了,将变量类型更改为double可以提高精度,并且您将得到预期的细粒度结果。

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. 根据IEEE 754编码,许多数字会有很小的变化以允许存储它们;此外,有效数字的数量可能会略有变化,因为它是二进制表示形式,而不是十进制表示形式。

Single precision (float) gives you 23 bits of significand, 8 bits of exponent, and 1 sign bit. 单精度(浮点数)为您提供23位有效数,8位指数和1个符号位。

Double precision (double) gives you 52 bits of significand, 11 bits of exponent, and 1 sign bit. 双精度(double)为您提供52位有效数,11位指数和1个符号位。

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

Change float to double if want more precision 如果需要更高的精度,请将float更改为double

double time, sec;   

and use %lf in sscanf . 并在sscanf使用%lf You will get the desired result. 您会得到理想的结果。

Live Demo 现场演示

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM