【问题标题】:Why do these two code snippets produce different results? (Float, Double precision)为什么这两个代码片段会产生不同的结果? (浮点型,双精度)
【发布时间】:2012-01-25 11:02:03
【问题描述】:

我才刚刚开始学习 C++,并且一直在搞乱浮点和双精度值。下面是两个代码 sn-ps,在我看来它们在做同样的事情但给出不同的结果。我错过了什么?有人可以解释第一个代码必须得到与第二个不同的结果所必须的精度错误吗?

int _tmain(int argc, _TCHAR* argv[])
{
    const float f = 0.1;
    const double d = 0.1;
    int counter = 0;

    for(counter; ((double)counter * f - (double)counter * d) < 0.34; counter++) {}

    cout << "Iterations = " << counter << "\n" ;

    system("pause");
    return 0;
}


int main (int argc, const char * argv[])
{
    float time_f = 0.1;    
    double time_d = 0.1;
    float total_f = 0;
    double total_d = 0;
    int count=0;
    double difference = 0;
    while (true) {
        total_d = count * time_d;
        total_f = count * time_f;
        if(total_f - total_d >= 0.34){

            break;
        }
        count++;

    }
    std::cout <<  count << "\n";
    system("pause");
}

我已经在 float 和 double 之间更改了 for 循环条件的转换,但值没有不同。

【问题讨论】:

标签: c++ floating-point double precision


【解决方案1】:

floatdouble 都有一个有限表示,这意味着它们 具有一系列离散值,而不仅仅是任何实际值。在 特别是,在您的示例中,0.1 没有精确的浮点数 我所知道的任何现代机器上的表示(所有这些机器都使用基础 在他们的实现中是 2 的幂——0.11/5 * 1/2,而任何是 1/5 的倍数都不能有有限 除非基数是 5 的倍数)。

结果是floatdouble 具有相同的底层 表示(通常不是这种情况),否则会有差异 只要count 与 0 不同。

这个主题的通常参考是 “什么 每个计算机科学家都应该了解浮点 算术”。直到您阅读并理解(或至少 理解含义)它,你不应该触摸机器浮动 点。

【讨论】:

    【解决方案2】:

    这两个代码 sn-ps 之间的区别在于演员表。 counter * f 在第一个 sn-p 中被强制转换为 double 并在第二个中存储到 float 变量。

    以下是它的外观示例:

    #include <stdio.h>
    
    int main(int argc, char* argv[])
    {
        const float f = 0.1;
        const double d = 0.1;
        int count = 0;
    
        for(count; (double)(count * f) - (double)(count * d) < 0.34; count++);
    
        printf("Iterations = %d\n", count);
        count = 0;
    
        while (true)
        {
            double total_d = count * d; // is equal to (double)(count * d)
            double total_f = count * f; // is equal to (double)(count * f)
            if (total_f - total_d >= 0.34)
                break;
            count++;
        }
        printf("Iterations = %d\n", count);
    
        return 0;
    }
    

    【讨论】:

      【解决方案3】:

      您还没有在此处将计数加倍:

      total_d = count * time_d;
      total_f = count * time_f;
      

      另外,这些循环永远不会结束,因为两个减法操作数具有相同的值:S

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-09-07
        • 1970-01-01
        • 1970-01-01
        • 2016-11-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-04-11
        相关资源
        最近更新 更多