Hi, i'm doing some work with double atm and i have what appears to be a simple expression. When i work this out in my head i get the answer to be 0. However running the code gives me a very obscure value -5.77338e-017
Any help as to what i am doing wrong, P.S the answer i am atfer is 0
double a = 0.96;
double b = 0.9;
double com = 30.00;
std::cout << a - ((2.00*(com/1000.00)) + b);
Its a difference in compilers and the way they handle floating point arithmetic. VC++ 2008 Express produces 0. Dev-C++ produces the value you quoted. Dev-C++ is an old compiler now and may have a few bugs. Maybe someone with CodeBlocks can try it to see if the bug has been fixed.
Ah, so using Dev is there anyway that this can be solved? As I would hate to have to swap to VC++ just to solve this problem. Using Dev Allows me to do some stuff whilst i'm in college :D Where as i wouldn't be able to do anything if i had to use VC++ :/
I'm aware Dev is old...perhaps i should have a look at Code::blocks.
It's not an "old compiler" issue, it's normal behaviour for floating point data calculations. You have not the right to an "exact" result for these calculations. Only integral numerical types get "exact' results. The "obscure" value -5.77338e-017 is a good approximation for least valued bits of double type mantissa. Now remember that 0.9 and 0.96 numbers (periodical binary fractions) have no exact double representation at all...
I would like to comment that the issue of getting 0 or getting 5.77e-17 is mainly a CPU issue. Intel and AMD use 80bit registers. This hides and creates a lot of numerical rounding error.
This is a nightmare in numerical code since as the code gets interspersed or threads are used or recursion is used, you don't know when the compiler requires to move that 80bit temporary into a memory storage at 64bit. However, at 128 bit (long double) it is certain and that make life a little easier.
Additionally, if you use gcc/g++ then you can use -ffloat-store to avoid the register problem and that gives you the correct IEEE result of 5.77e-17 (long double) and 0 for (double). [Note that -ffloat-store can be a seriously CPU expensive option]
If you use long double then the results tend to be more IEEE based. If it matters to you then use the correct compiler flag.