CodeBlocks C ++ error

I was doing something in C ++ (CodeBlocks) but I found a strange problem. I sent my code to my friend (he tested it in DevC ++) and it worked. I have tried these two codes:

#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; } 
}

      

But then I changed the main function (and it didn't work):

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; }
}

      

Does anyone know what the problem is?

0


source to share


4 answers


The problem is math.h doesn't work, so I have to use cmath. Secondly, not int, but float or double.

code:



#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


source


Unless you tell us what your "weird" error was, I guess your second piece of code prints:

Does not work

The problem is you are comparing floating point numbers because it pow()

returns floating points

, see function definitionpow()

.

Floating point math is not accurate due to rounding error . Simple values ​​such as 9.0 cannot be accurately represented using binary floating point numbers, and the limited precision of floating point numbers means that small changes in the order of operations can change the result. Different compilers and processor architectures store temporary results at different settings, so the results will vary depending on the details of your environment. For example:

    float a = 9.0 + 16.0
    float b = 25.0
    if(a == b) // can be false!
    if(a >= b) // can also be false!

      

Even

    if( Math.abs(a-b) < 0.00001) // wrong - don't do this

      

This is a bad way to do it, because the fixed epsilon

(0.00001) chosen because it "looks small" may be too large when the numbers being compared are also very small.

I personally use the following method,



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;
        }
    }

      

And don't forget to read What Every Computer Scientist Should Know About Floating Point Arithmetic !

Link: This is a link to my answer.

Edit: As the OP's problem regarding C++

, so here is the edited version nearlyEqual()

:

#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;
}

      

Output:

Job

Compiler: Cygwin C ++ Compiler.

Cygwin version: 1.7.25

+3


source


Variable types.

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/

try

> 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;
>     } }

      

The above doesn't work in VS 2013.

I got it to work using the function

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);
  }
}

      

This seems to indicate that, as Corycramer points out, there is a floating point rounding error. He is also correct that the d suffix is ​​not valid for double literals, so I also changed the code to fix that.

0


source


He worked for ideone.com too! http://ideone.com/3XcY4G

    int main() 
{
    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; }
}

      

0


source







All Articles