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

Floating point to integer conversion

Brian_G
Beginner
860 Views
I am migrating some legacy code from CVF to IVF, and I am getting different results when a floating point calculation is converted to an integer. I have written a small program to illustrate this issue. The program converts a floating point calculation to an integer by direct assignment, by the INT function, and by the NINT function.
Code:
program TestFloatingPointToInteger

implicit none

real *4 fDeckLength
real *4 fSpanLength
real *4 fWheelAdvDenominator
real *4 fStep
real *4 fNumSteps
integer *4 iNumSteps
integer *4 iNumSteps_INT
integer *4 iNumSteps_NINT

fDeckLength = 51.59
fSpanLength = 51.59
fWheelAdvDenominator = 100.0

fStep = fSpanLength / fWheelAdvDenominator

fNumSteps = fDeckLength / fStep
iNumSteps = fDeckLength / fStep
iNumSteps_INT = INT(fDeckLength / fStep)
iNumSteps_NINT = NINT(fDeckLength / fStep)

write(*,1000) fNumSteps, iNumSteps, iNumSteps_INT, iNumSteps_NINT
1000 format(1x,'fNumSteps      = ',g22.12,/, &
            1x,'iNumSteps      = ',i,' (Direct assignment)',/, &
            1x,'iNumSteps_INT  = ',i,/, &
            1x,'iNumSteps_NINT = ',i)

iNumSteps = fNumSteps
write(*,2000) iNumSteps
2000 format(1x,'iNumSteps      = ',i,' (Intermediate calc)')

write(*,3000) fDeckLength, fSpanLength, fWheelAdvDenominator, fStep
3000 format(1x,'fDeckLength          = ',g22.12,/, &
            1x,'fSpanLength          = ',g22.12,/, &
            1x,'fWheelAdvDenominator = ',g22.12,/, &
            1x,'fStep                = ',g22.12)

end

Output from CVF:
fNumSteps = 100.000000000
iNumSteps = 99 (Direct assignment)
iNumSteps_INT = 99
iNumSteps_NINT = 100
iNumSteps = 100 (Intermediate calc)
fDeckLength = 51.5900001526
fSpanLength = 51.5900001526
fWheelAdvDenominator = 100.000000000
fStep = 0.515900015831
Output from IFV:
fNumSteps = 100.000000000
iNumSteps = 100 (Direct assignment)
iNumSteps_INT = 100
iNumSteps_NINT = 100
iNumSteps = 100 (Intermediate calc)
fDeckLength = 51.5900001526
fSpanLength = 51.5900001526
fWheelAdvDenominator = 100.000000000
fStep = 0.515900015831
Why is IVF rounding to the nearest integer in all cases of the conversion, while CVF is truncating the floating point for the direct assignment and INT function? I have tried several combinations of compiler options for floating points with no luck. If the number of steps is stored in a floating point variable and then stored in an integer, both compilers round to the nearest integer.
Any suggestions would be helpful.
0 Kudos
2 Replies
Steven_L_Intel1
Employee
860 Views
Your description of what the two compilers are doing is not correct.

CVF is doing some of the calculations in double precision and the divide is giving you a value slightly under 100, which the INT truncates to 99. This is supported by your note that if you assign intermediate values to variables, you get consistent results.

Try CVF with /fltconsistency to see if it changes things.
0 Kudos
Brian_G
Beginner
860 Views

I changed the CFV project to use /fltconsistency, but the results were the same. I can see that CFV is giving a value just under 100.0, which then gets truncated to 99 when INT is used. CFV uses double precision for intermediate calcuations, as you said, but doesn't IFV as well if the "Default Consistency" is used? I see that IVF uses 80 bits (not 64) when the "Improve Consistency" or /Op compiler option is specified.

In the IVF program, I have no optimization specified and I'm using the "Default Consistency." Therefore, I do not understand why IVF is producing different floating point results than CVF and in my case, i.e., a value that is just over 100.0.

0 Kudos
Reply