Unless you tell us what was your "weird" error, I'm assuming that, your second snippet code prints:
Doesn't work
The problem is, you are comparing floating point numbers because pow() returns floating points, see the definition of pow() function.
Floating point math is not exact because of Rounding Errors. Simple values like 9.0 cannot be precisely represented using binary floating point numbers, and the limited precision of floating point numbers means that slight changes in the order of operations can change the result. Different compilers and CPU architectures store temporary results at different precisions, so results will differ 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 a fixed epsilon (0.00001) chosen because it “looks small” could actually be way too large when the numbers being compared are very small as well.
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!
Reference: This is the reference of my answer.
Edit: As the OP's problem concerning about C++, so here is the edited version of 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;
}
The output is :
Works
Compiler : Cygwin C++ Compiler.
Cygwin Version: 1.7.25