如何解决C ++中浮点运算的舍入问题?

时间:2010-12-02 20:14:25

标签: c++ floating-accuracy

我遇到浮点运算不精确的一些问题。我正在尝试根据加权公式计算得分,其中每个输入变量的重量大约是下一个重要值的20倍。然而输入是实数,所以我最终使用double来存储结果。下面的代码存在丢失E1和E2之间差异的问题。

此代码对性能敏感,因此我需要找到解决此问题的有效方法。我想把我的输入乘以一百然后再使用一个int(因为我认为这个就足够精确了),但我怀疑这是最好的解决方案,因此问题。

#include <iostream>

int main()
{
    double score1, score2;
    float a  = 2.75 ;
    float b  = 5.25 ;
    float c  = 5.25 ;
    float d  = 2.75 ;
    float E1 = 3    ;
    float E2 = 6    ;

    score1 = 20 * b - 1 * a + 0.05 * d  /* - 0.0025 * c*/ + 0.0001 * E1 ;
    score2 = 20 * b - 1 * a + 0.05 * d  /* - 0.0025 * c*/ + 0.0001 * E2 ;

    std::cout << score1 << std::endl;
    std::cout << score2 << std::endl;

    std::cin.get();
    return 0;
}

//ouputs:
//102.388
//102.388

4 个答案:

答案 0 :(得分:4)

  1. 您没有输出整个值,请使用cout << setprecision(number_of_digits) << score1 << endl;
  2. 您的分数计算中需要多少个有效数字?

答案 1 :(得分:3)

  

我想过将我的输入乘以一百然后再使用一个int(因为我觉得这很精确),但我怀疑这是最好的解决方案

考虑到你所展示的价值,我会说是。

答案 2 :(得分:1)

http://ideone.com/qqTB3向您显示差异并未丢失,但实际上与您期望的一样大(达到浮点精度,即双倍的15位十进制数字)。

答案 3 :(得分:1)

让我们看看这段代码中发生了什么:

score1 = 20 * b - 1 * a + 0.05 * d  /* - 0.0025 * c*/ + 0.0001 * E1 ;

// Multiplication division happens first:

float  tmp1 = static_cast<float>(20) * b;      // 20 cast to float.
float  tmp2 = static_cast<float>(1)  * a;      // 1  cast to float.
double tmp3 = 0.05   * static_cast<double>(d); // d converted to double as 0.05 is double
double tmp4 = 0.0001 * static_cast<double>(E1);// E1 cast to double as 0.0001 is double

// Addition and subtraction now happen
float  tmp5  = tmp1 - tmp2;
double tmp6  = static_cast<double>(tmp5) + tmp3; // tmp5 cast to double as tmp3 is a double.
double tmp7  = tmp6 + tmp4;
score1       = tmp7;

如果我们在脑海中这样做:

tmp1 = 105.0
tmp2 =   2.75
tmp3 =   0.1375
tmp4 =   0.0003
tmp5 = 107.75
tmp6 = 107.8875
tmp7 = 107.8878

这些值应保持精度:
但是当你打印出来时,双精度的默认精度是3位小数。

std::cout << 107.8878;
> 107.888

所以设置精度:

std::cout << std::setprecision(15) << 107.8878 << "\n";
> 107.8878