C 浮点上的奇怪近似



我有以下代码:

#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 %.7gn", step1, step1); // 0.425000 0.4250001
    float step2 = min + (max - min) * (rank + 1) / total - step; //should be 0.848
    printf("%f %.7gn", step2, step2); // 0.848000 0.848
    float noc = (step2 - step1 + step) / step; //should be 212,5
    printf("%f %.7gn", noc, noc); // 212.499985 212.5
    int nol = 1200;
    int result = (int)nol * noc; //should be 255000
    printf("%dn", result); // 254999
    return 0;
}

这是从我必须做的项目中分离出来的代码片段。最终结果应该是 255000,但由于某些原因,它显示了254999。有人可以解释一下在这个过程中发生了什么吗?我在某处读到,将浮点数乘以 10^k 然后除回来可以解决这些问题,但在这种情况下,由于变量步长从 0.000001 到 0.1 不等,我实际上不能使用它(同样,我不能使用定义的 EPSILON)。我还能做什么?

提前感谢!

PS:我也用过双精度和长双精度,但有同样的问题,只是这次错误是从更远的小数传播的。我正在使用 gcc 4.8.2,在 Ubuntu 14.04.1 下。

断与舍入。

由于 FP 算术的细微舍入效应,乘积nol * noc可能略小于整数值。 转换为 int 会导致分数截断。 建议在转换为int之前四舍五入。

#include <math.h>
int result = (int) roundf(nol * noc);
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

相关内容

  • 没有找到相关文章

最新更新