Suppose I have a very small float a (for instance a=0.5) that enters the following expression:
6000.f * a * a;
Does the order of the operands make any difference? Is it better to write
6000.f * (a*a);
Or even
float result = a*a;
result *= 6000.f;
I’ve checked the classic What Every Computer Scientist Should Know About Floating-Point Arithmetic but couldn’t find anything.
Is there an optimal way to order operands in a floating point operation?
It really depends on the values and your goals. For instance if
ais very small,a*amight be zero, whereas6000.0*a*a(which means(6000.0*a)*a) could still be nonzero. For avoiding overflow and underflow, the general rule is to apply the associative law to first perform multiplications where the operands’ logs have opposite sign, which means squaring first is generally a worst strategy. On the other hand, for performance reasons, squaring first might be a very good strategy if you can reuse the value of the square. You may encounter yet another issue, which could matter more for correctness than overflow/underflow issues if your numbers will never be very close to zero or infinity: certain multiplications may be guaranteed to have exact answers, while others involve rounding. In general you’ll get the most accurate results by minimizing the number of rounding steps that happen.