If two very small numbers are multiplied, the result underflows.
If you know in advance that the operands in a multiplication (or subtraction) may be small and underflow is likely, run the calculation in double precision and convert the result to single precision later.
For example, a dot product loop like this:
real sum, a(maxn), b(maxn) ... do i =1, n sum = sum + a(i)*b(i) enddo |
where the a(*) and b(*) are known to have small elements, should be run in double precision to preserve numeric accuracy:
real a(maxn), b(maxn) double sum ... do i =1, n sum = sum + a(i)*dble(b(i)) enddo |
Doing so may also improve performance due to the software resolution of excessive underflows caused by the original loop. However, there is no hard and fast rule here; experiment with your intensely computational code to determine the most profitable solutions.