Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

real rounding

jim_cox
Beginner
927 Views
We are finding some awkward rounding going on with real numbers


For example our program has

real beta
beta = 1.0

real betastep
betastep = 0.01

but when you examine with the debugger betastep = 9.9999998E-3, which is not quite the same

unfortuantely this showing up in our results - after a number of loops of

beta = beta - betastep


the beta counter drifts off

5.98004 instead of 5.98, 4.63001 instead of 4.63 etc


I've tried the /fp:strict and /fp:precise and /Qfp_port compiler switches, but they dont seem to change anything


Is there an easy fix?

Or is it just 'one-of-those' rounding things?



Thankx

Jim
0 Kudos
5 Replies
DavidWhite
Valued Contributor II
927 Views
Real numbers can rarely be expressed exactly in binary, so this problem is typical of working with reals.

Is your example typical of what you want to do - always an exact number of steps (in this case 100).

Suggest that you use an integer counter, and calculate
Beta = Betastart - (I-1)*Betastep

or something silimar.

Regards,


David
0 Kudos
Lars_Jakobsen
Beginner
927 Views

You could delay the drift (at lest I would think so) ifyou use double precission.

real(8) beta = 1.0d
real(8) betastep=0.01d

Regards

Lars

0 Kudos
SergeyKostrov
Valued Contributor II
927 Views

You're dealing with limitations of IEEE 754 Standard. In case of a single-precision data type ( 24-bit precision) a rounding or inexact
issues start affecting a precision very quickly. The only solution is touse a double-precision data type ( 53-bit or 64-bitprecisions ) instead.

Best regards,
Sergey

0 Kudos
TimP
Honored Contributor III
927 Views
Depending on what you are looking for, the "easy fix" might resemble;

do i = 1,100
beta = (100 - i) / 100.
.....

Not only would this avoid drift, it is a classic vectorizability transformation.
I think David (in the earlier response) may have meant this.
0 Kudos
jimdempseyatthecove
Honored Contributor III
927 Views
real beta, betaBase
betaBase = 1.0

real betaStepMultiplier, betaStepInverse
betaStepMultiplier = 0.0
betaStepInverse = 100.0

do I=1,N
beta = betaBase - (betaStepMultiplier / betaStepInverse)
...
betaStepMultiplier = betaStepMultiplier + 1.0
end do

The above will provide better precision, and more importantly, will not accumulate roundoff errors.
Note, division is relatively fast on current processors.

Jim Dempsey
0 Kudos
Reply