与 abs() 的方程给出了错误的答案 (gcc/g++)

Juh*_*a P 2 c++

不知怎的,我从涉及库函数abs()的方程中得到了错误的结果。这是我存在问题的代码:

main.cpp -------------------------------------

#include <iostream>
#include <cmath>

#include "test999.h"

using namespace std;

int main()
{
    float n = 11;
    ak r;

    r = test(n);
    printf("\n");
    for(int i = 0; i < n; i++){
        printf("r.yp[%d] = %3.7f \n", i, r.yp[i]);
    }

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

test999.h ------------------------------------------

struct ak{
    float yp[20];
};

ak test(int n){

    float u[] = {0, 0, 0, 0, 0, 0, 0, 0.5, 4.5, 35, 10, 25, 40, 55};
    ak r;
    float a, b;

    for(int i = 0; i < n; i++){
       a = abs(u[i+3] - u[i+2]);
       b = abs(u[i+1] - u[i]);

       printf("i = %d   a = u[%d](%2.4f) - u[%d](%2.4f) = %2.4f \n        b = u[%d]-u[%d] = %2.4f (%2.4f - %2.4f) \n", i, i+3, u[i+3], i+2, u[i+2], a, i+1,  u[i+1], i, u[i], b);

       if ((a+b) != 0.0f){
          r.yp[i] = (a * u[i+1] + b * u[i+2]) / (a+b);
       }
       else{
          r.yp[i] = (u[i+2] + u[i+1]) / 2.0f;
       }
       printf("yp[%d] = %2.4f \n\n", i, r.yp[i]);
    }
    return r;
}
Run Code Online (Sandbox Code Playgroud)

并且它会导致abs(0.5)-0.0(情况i=4)和abs(35.0)-4.5(情况i=6)的方程的错误值:

在此输入图像描述

更改方程以使用 std::abs() 可以正确计算:

在此输入图像描述

如果我将所有内容移至 main.cpp 模块,这两种情况都会起作用,是否只是因为我制作了缺陷代码......或者从 0.5 舍入到 0.0 发生在我应该考虑的地方......?

for*_*818 12

std::abs(int),有std::abs(float)。前者继承自 C abs(int)。在 C 中,浮点没有重载,它被称为fabs(也可用作std::fabs)。

您混淆了using namespace std;实际调用的函数。请注意,您将其放在 中main,但不在标头中,这实际上很好,但在 中仍然有害main,因为一旦将所有代码放入 中main,突然会调用不同的函数。没有using namespace std;abs(some_float)召唤::abs(int)。与using namespace std;abs(some_float)召唤std::abs(float)

请注意,允许从 C 继承的头文件,但不保证在全局命名空间中引入名称,因此您也可能会收到编译器错误。

替换absstd::abs并删除using namespace std. 有关不提取所有名称的更多原因,std请参阅为什么“使用名称空间 std;” 被认为是不好的做法?