I have a complex little formula in my code in which variables are subtracted that are very close together. Their difference is many orders of magnitude smaller than the numbers being subtracted. C is evaluating the expression incorrectly.
The formula is as follows (all variables are doubles)
The variables have the following values as calculated by the codeCode:operand = a*a*(108.0*a*c*c*c + 108.0*b*b*b*d - 27.0*b*b*c*c - 486.0*a*b*c*d + 729.0*a*a*d*d);
compared to composite values calculated by hand using a calculator with better precision:Code:a: 2.0287864134649038e+07 b: 1.9026877897384940e+04 c: 4.4610669723446748e+00 d: -3.7933051584501112e-29 108.0*a*c*c*c: 1.9452539813523886e+11 108.0*b*b*b*d: -2.8219163158723021e-14 27.0*b*b*c*c: 1.9452539813523883e+11 486.0*a*b*c*d: -3.1746558553563405e-14 729.0*a*a*d*d: 4.3175338098787823e-40
You can see that there are subtle differences between the values in the code and there, and that the first and third term almost cancel each other out, except for in the last few decimal places, which are not especially reliable.Code:108.0*a*c*c*c: 1.94525398135238912527e11 108.0*b*b*b*d: -2.82191631587230194283e-14 27.0*b*b*c*c: 1.94525398135238861191e11 486.0*a*b*c*d: -3.17465585535634052349e-14 729.0*a*a*d*d: 4.31753380987878243389e-40
The values calculated by the code give a value for operand of 1.2560956774113516e+10
The correct answer is 2.11297657006282327491e10.
So: I am bumping up against the limits of hardware precision here, I think. I need a way to reliable subtract numbers that only differ in maybe the 14th decimal place. Is such a things possible?
I have been playing around with order of operations in the formula, factoring out various terms. The value of operand can be changed dramatically just by changing the order in which things are done.
I would like to avoid using a higher precision library if at all possible - this will be executed several billion times in the course of a run and using software precision is going to slow things down a lot. Do I have alternatives?
Thanks