CodeBlocks C++ Bug -
i doing in c++ (codeblocks), found weird problem. sent code friend (he tested in devc++) , worked. tried these 2 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, changed main function (and 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; } } anyone knows what's problem ?
unless tell "weird" error, i'm assuming that, second snippet code prints:
doesn't work
the problem is, comparing floating point numbers because pow() returns floating points, see definition of pow() function.
floating point math not exact because of rounding errors. simple values 9.0 cannot precisely represented using binary floating point numbers, , limited precision of floating point numbers means slight changes in order of operations can change result. different compilers , cpu architectures store temporary results @ different precisions, results differ depending on details of environment. example:
float = 9.0 + 16.0 float b = 25.0 if(a == b) // can false! if(a >= b) // can false! even
if( math.abs(a-b) < 0.00001) // wrong - don't this bad way because fixed epsilon (0.00001) chosen because “looks small” way large when numbers being compared small well.
i use 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) { // or b 0 or both extremely close // relative error 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 read what every computer scientist should know floating-point arithmetic!
reference: this reference of answer.
edit: op's problem concerning c++, here 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 :
works
compiler : cygwin c++ compiler.
cygwin version: 1.7.25
Comments
Post a Comment