首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >CodeBlocks C++ Bug

CodeBlocks C++ Bug
EN

Stack Overflow用户
提问于 2015-06-03 19:28:03
回答 4查看 724关注 0票数 0

我在C++ (CodeBlocks)做一些事情,但我发现了一个奇怪的问题。我把我的代码发送给了我的朋友(他在DevC++中测试过),它起了作用。我试过这两种密码:

代码语言:javascript
复制
#include <iostream>
#include <math.h>
using namespace std;

int main() //this function works
{
    if (pow(3, 2) + pow(4, 2) == pow(5, 2)) {
        cout << "Works" << endl;
    } else { cout << "Nope" << endl; } 
}

但是,然后我像这样更改了主要功能(但它没有工作):

代码语言:javascript
复制
int main() //this function doesn't work
{
    int t1 = 3, t2 = 4, t3 = 5;
    if (pow(t1, 2) + pow(t2, 2) == pow(t3, 2)) {
        cout << "Works" << endl;
    } else { cout << "Doesn't work" << endl; }
}

有人知道问题出在哪里吗?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2015-06-05 11:15:34

问题是数学不起作用,所以我不得不使用数学。第二,不是int,而是浮动或加倍。

代码:

代码语言:javascript
复制
#include <iostream>
#include <cmath>

using namespace std;

int main()
{

    float t1 = 3, t2 = 4, t3 = 5;

    if (pow(t1, 2) + pow(t2, 2) == pow(t3, 2)) {
        cout << "PT" << endl;
    }
    else {
        cout << pow(t1, 2) + pow(t2, 2) << endl;
        cout << pow(t3, 2) << endl;
    }

}
票数 -1
EN

Stack Overflow用户

发布于 2015-06-03 20:49:51

除非您告诉我们您的“奇怪”错误是什么,否则我假设,您的第二个代码片段打印:

不管用

问题是,您正在比较浮点数,因为pow()返回floating points函数

浮点的数学是不准确的,因为舍入误差。像9.0这样的简单值不能精确地用二进制浮点数表示,浮点数字的有限精度意味着操作顺序的微小变化可以改变结果。不同的编译器和CPU体系结构以不同的精度存储临时结果,因此根据环境的详细信息,结果将有所不同。例如:

代码语言:javascript
复制
    float a = 9.0 + 16.0
    float b = 25.0
    if(a == b) // can be false!
    if(a >= b) // can also be false!

甚至

代码语言:javascript
复制
    if( Math.abs(a-b) < 0.00001) // wrong - don't do this

这是一个不好的方法,因为选择一个固定的epsilon (0.00001)是因为它“看起来很小”,当比较的数字也很小时,它实际上可能太大了。

我个人使用以下方法,

代码语言:javascript
复制
public static boolean nearlyEqual(float a, float b, float epsilon) {
        final float absA = Math.abs(a);
        final float absB = Math.abs(b);
        final float diff = Math.abs(a - b);

        if (a == b) { // shortcut, handles infinities
            return true;
        } else if (a == 0 || b == 0 || diff < Float.MIN_NORMAL) {
            // a or b is zero or both are extremely close to it
            // relative error is less meaningful here
            return diff < (epsilon * Float.MIN_NORMAL);
        } else { // use relative error
            return diff / Math.min((absA + absB), Float.MAX_VALUE) < epsilon;
        }
    }

忘了关于浮点算法,每个计算机科学家应该知道什么?

参考: 是我答案的参考。

编辑:是OP关于C++的问题,下面是nearlyEqual()的编辑版本:

代码语言:javascript
复制
#include <iostream>     // std::cout
#include <cmath>        // std::abs
#include <algorithm>    // std::min
using namespace std;

#define MIN_NORMAL 1.17549435E-38f
#define MAX_VALUE 3.4028235E38f

bool nearlyEqual(float a, float b, float epsilon) {
    float absA = std::abs(a);
    float absB = std::abs(b);
    float diff = std::abs(a - b);

    if (a == b) {
        return true;
    } else if (a == 0 || b == 0 || diff < MIN_NORMAL) {
        return diff < (epsilon * MIN_NORMAL);
    } else {
        return diff / std::min(absA + absB, MAX_VALUE) < epsilon;
    }
}

int main(void) {
    float t1 = 3.0, t2 = 4.0, t3 = 5.0, epsilon = 0.0000000001; // don't use int here!
    if (nearlyEqual((pow(t1, 2) + pow(t2, 2)), pow(t3, 2), epsilon)) {
        cout << "Works" << endl;
    } else {
        cout << "Doesn't work" << endl;
    }
    return 0;
}

产出如下:

作品

编译器: Cygwin C++编译器。

Cygwin版本: 1.7.25

票数 3
EN

Stack Overflow用户

发布于 2015-06-03 19:32:42

变量类型。

代码语言:javascript
复制
double pow (double base     , double exponent);
     float pow (float base      , float exponent);
long double pow (long double base, long double exponent);
     double pow (Type1 base      , Type2 exponent);        // additional overloads

http://www.cplusplus.com/reference/cmath/pow/

试一试

代码语言:javascript
复制
> int main() {
>     double d1 = 3.0, d2 = 4.0, d3 = 5.0;
>     if(pow(d1,2) + pow(d2,2) == pow(d3,2)) {
>         cout << "Works" << endl;
>     }
>     else {
>         cout << "Nope" << endl;
>     } }

以上内容也不适用于2013年。

我用了一个函数

代码语言:javascript
复制
bool CheckPyth(double a, double b, double c) {
  double aa = pow(a,2);
  double bb = pow(b,2);
  double cc = pow(c,2);

  if(aa + bb == cc) {
    return(true);
  }
  else {
    return(false);
  }
}

这似乎表明,正如CoryKramer指出的,它是一个浮点舍入错误。关于d后缀对双字面值无效的说法也是正确的,所以我也修改了代码以纠正这个错误。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30628945

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档