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

Extend Precision of Single-Precision Constants

judios
Beginner
1,489 Views
How does this switch (/fpconstant) really works???

Havingthe following code:

===============
DOUBLE PRECISION R

E = 28373530

R = 1 / (2. * E)

WRITE (6,*) R
===============

The output is : 1.762205847910536E-008

It does not matterif the switch /fpconstant is set to [yes] or [no], it will prodeuce the same output.

Computing R as
R = 1 /(2D0 * E ), or
R = 1D0 / ( 2. * E),or
R = 1D0 / ( 2D0 * E )

The output is1.762205830575187E-008

Is not this the value one should expect when using [Yes] in /fpconstant???

What should one do to force Intel Fortran to compute the constant values 1., and 2. as double precision values in this expresion? R = 1. / ( 2. * E )

Thanks.
0 Kudos
1 Solution
Steven_L_Intel1
Employee
1,489 Views
Your code is not affected by /fpconstant. You have the single-precision variable E that is assigned a value with more significant digits than single can hold. /fpconstant controls the behavior when a single precision literal value is used in a context where it will be converted to double. Without it, which is the default, you lose any extra digits you may have entered. With /fpconstant, the literal constant is held in the higher precision until used. Here's an example demonstrating it.

[fortran]REAL(8) PI
PI = 3.141592653589793
PRINT *, PI
END[/fortran]

And here's the result without and with /fpconstant:

[plain]C:Projects>ifort /nologo fpc.f90

C:Projects>fpc.exe
3.14159274101257

C:Projects>ifort /nologo /fpconstant fpc.f90

C:Projects>fpc.exe
3.14159265358979[/plain]

View solution in original post

0 Kudos
6 Replies
Steven_L_Intel1
Employee
1,490 Views
Your code is not affected by /fpconstant. You have the single-precision variable E that is assigned a value with more significant digits than single can hold. /fpconstant controls the behavior when a single precision literal value is used in a context where it will be converted to double. Without it, which is the default, you lose any extra digits you may have entered. With /fpconstant, the literal constant is held in the higher precision until used. Here's an example demonstrating it.

[fortran]REAL(8) PI
PI = 3.141592653589793
PRINT *, PI
END[/fortran]

And here's the result without and with /fpconstant:

[plain]C:Projects>ifort /nologo fpc.f90

C:Projects>fpc.exe
3.14159274101257

C:Projects>ifort /nologo /fpconstant fpc.f90

C:Projects>fpc.exe
3.14159265358979[/plain]
0 Kudos
mecej4
Honored Contributor III
1,489 Views
(A minor comment: none of the values of Pi in #1 is correct beyond five significant digits.) EDIT: FIXED; see #3
0 Kudos
Steven_L_Intel1
Employee
1,489 Views
Yeah - I dropped a digit. Fixed.
0 Kudos
judios
Beginner
1,489 Views
Steve,

Thanks to your explanation about the behabior of /fpconstant, I understand that it would not help in my need.

I amwondering, if there is any other switch that force the intel compiler to treat 1.0 and 2.0 as double precision numbers while evaluating the expression R = 1.0 / (2.0 * E).

I amcompiling a good number of fortran 77 files using Intel Fortran. Those files were originally compiled using watcom 77.

With watcom the following threeexpresions produce the same result, while intel fortran produces a different result for the first expresion.

R = 1.0 /(2.0 * E)
R = 1D0 / (2.0 * E)
R = 1.0 / (2D0 * E)

Thanks.
0 Kudos
Steven_L_Intel1
Employee
1,489 Views
I am somewhat surprised by the Watcom results, but F77 was rather ambiguous in this regard. The only thing I can suggest is /real_size:64, which is a rather big hammer. The problem with the first expression is that the right side is all single-precision.

Actually, you might try /arch:ia32 and see what you get. This will be slower.
0 Kudos
judios
Beginner
1,489 Views

/arch:ia32 does not change the behavior.

/real_size:64 does produce the same results as watcom. However, it will change the size of all the real variables in the program, and will reallign the COMMON. At this point it will be faster and safer to fix all the expresions adding the "D0" than trying to remap the common.

Thanks Steve!
0 Kudos
Reply