我有以下代码:
#include<stdio.h>
int main(int argc, char const *argv[])
{
float min, max, step;
min = -0.85, max = 0.85, step = 0.002;
int rank = 3, total = 4;
float step1 = min + (max - min) * rank / total; // should be 0.425
printf("%f %.7g\n", step1, step1); // 0.425000 0.4250001
float step2 = min + (max - min) * (rank + 1) / total - step; //should be 0.848
printf("%f %.7g\n", step2, step2); // 0.848000 0.848
float noc = (step2 - step1 + step) / step; //should be 212,5
printf("%f %.7g\n", noc, noc); // 212.499985 212.5
int nol = 1200;
int result = (int)nol * noc; //should be 255000
printf("%d\n", result); // 254999
return 0;
}
这是一个与我必须完成的项目隔离的代码片段。最终结果应该是255000,但是由于某些原因,它显示了254999.有人可以解释一下这个过程中会发生什么吗?我读过某个地方,将浮动数乘以10 ^ k,然后再划分解决了这些问题,但在这种情况下,由于变量步长从0.000001变化到0.1,我实际上无法使用它(以同样的方式,我不能使用定义的EPSILON)。我还可以做些什么?
提前致谢!
P.S。:我也使用了double和long double,但是遇到同样的问题,只有这个时间错误从另一个小数传播。我在Ubuntu 14.04.1下使用gcc 4.8.2。
答案 0 :(得分:1)
截断与舍入。
由于FP算法的细微舍入效应,乘积nol * noc
可能略小于整数值。转换为int
会导致小数截断。在转换为int
之前建议舍入。
#include <math.h>
int result = (int) roundf(nol * noc);
答案 1 :(得分:0)
the significant problem(s) are:
1) mixing floating point and double with integer math
--so the compiler promotes all the math to float (or double)
2) not all numbers can be expressed exactly in float
3) --the initialization of min, max, step are taking double literals
and converting them to float
--even double cannot express all values exactly
--some precision is lost when performing the conversion from double to float
4) this code excerpt: (rank + 1) / total is always = 1
--(although the many conversions may result in being 'not exactly' 1)
5) argc and argv are not referenced in your code.
--this, given that all warnings are enabled, will rise two warnings
at compile time about unused parameters
6) this line in your code is not correct syntax
--(although the compiler might not complain) #include<stdio.h>
--it should be #include <stdio.h>
--sometimes spaces count, sometimes they dont