【问题标题】:Why are these 2 versions of code giving different outputs为什么这两个版本的代码给出不同的输出
【发布时间】:2018-10-02 21:33:23
【问题描述】:

我有两个版本的相同多项式,但它们给出的输出明显不同,我不知道为什么。

// Example program
#include <iostream>
#include <string>
#include <math.h>

float v1(float alpha)
{
    alpha = 1.0-alpha;
    alpha = 1.0-pow(alpha, 5.0)*6.0 - 15.0*pow(alpha,4.0) +10.0*pow(alpha,3.0);
    return alpha;
}

float v2(float alpha)
{
    alpha = 1.0-alpha;
    alpha = 1.0-alpha*alpha*alpha*(alpha*((alpha*6.0) -15.0) + 10.0);
    return alpha;
}

int main()
{
    for(float t=0; t<=1; t+=0.1)
    {
        float a1 = v1(t);
        float a2 = v2(t);
        std::cout<< a1 << ", " << a2 << std::endl;
    }

}

输出:

-10, 0
-5.09444, 0.00856005
-1.99008, 0.05792
-0.17992, 0.16308
0.74944, 0.31744
1.125, 0.5
1.19456, 0.68256
1.13392, 0.83692
1.05408, 0.94208
1.00844, 0.99144

【问题讨论】:

  • 因为浮点运算。
  • 他们做的事情非常不同。这不仅是因为浮点问题,而且函数确实计算了不同的东西。
  • 看看 IEEE 浮点数是如何构成的,你就会明白
  • 括号的顺序我假设 1.0 - [ alpha pow(alpha, 5.0)*6.0 ] - [15.0*pow(alpha,4.0) ] + [ 10.0*pow(alpha,3.0)] 我替换some( for [ 使步骤更清晰
  • for(float t=0; t&lt;=1; t+=0.1) -- 请注意,将0.1 添加到float 不会产生准确的结果。如果循环的终止条件是t &lt;= 10 或更高,您可能会看到循环中的准确性损失(循环不会执行您预期的次数)。

标签: c++ math polynomial-math polynomials


【解决方案1】:

v2 中的表达式在数学上等价于

1.0 - (6*pow(alpha, 5) - 15*pow(alpha, 4) + 10*pow(alpha, 3))

注意额外的括号。你的两个函数are not equivalent 出于同样的原因1 - x^2 + x 不等于1 - (x^2 + x)

如果您在 v1 中的表达式周围添加一组额外的括号,您会从两个函数中得到 same result(除了一些小的浮点舍入错误)。

【讨论】:

  • 天哪,我今天早些时候一定很累,当然这些不等同
最近更新 更多