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

fpconstant issue

Adrian_F_1
Beginner
1,007 Views

I always use /fpconstant to save having to append d0 to all my constants.  As far I was aware this has always worked.  But now it works for one constant but not another.

      program ww
      implicit none
      real*8 :: KTOFShift      = -459.67
      real*8 :: KTOFFact       = 1.8
      write(6,*) KTOFShift
      write(6,*) KTOFFact
      end

gives:

ifort  ww.f90
ww
  -459.670013427734
   1.79999995231628

ifort  ww.f90 /fpconstant
ww
  -459.670013427734
   1.80000000000000

ie. the second constant gets doubled, but not the first.  Why?

0 Kudos
24 Replies
mecej4
Honored Contributor III
728 Views

I found that if you write +459.67 on Line-3, instead of -459.67, the correct 64-bit representation is produced. I have not experimented to check whether this incorrect behavior occurs with all negative constants.

[P.S.]Correction: I had actually tried '459.67' instead of '+459.67'. See #8.

0 Kudos
Steven_L_Intel1
Employee
728 Views

I find that this has been broken for many years - going back to 12.0 (earliest I tried it with). Very strange. It also works ok in assignment statements and DATA, but not initialization expressions in a declaration. I will report it to the developers, but also strongly suggest that you modify your code to not depend on this nonstandard behavior. Issue ID is DPD200371869.

0 Kudos
Adrian_F_1
Beginner
728 Views

What is the standard?  To write d0 after every constant?  Very ugly.

0 Kudos
Steven_L_Intel1
Employee
728 Views

The standard is that if you leave off D0 or a kind specifier then it is a "default real" value or single precision. You can use D0 or you can use a kind specifier. "real*8" is also nonstandard.

A standard approach would be:

integer, parameter :: DP = SELECTED_REAL_KIND(15,100)
real(DP) :: KTOFShift = -459.67_DP

 

0 Kudos
Adrian_F_1
Beginner
728 Views

_DP just as ugly as D0.  So /fpconstant is being phased out?

Adrian

0 Kudos
Adrian_F_1
Beginner
728 Views

mecej4 wrote:

I found that if you write +459.67 on Line-3, instead of -459.67, the correct 64-bit representation is produced. I have not experimented to check whether this incorrect behavior occurs with all negative constants.

I got the same problem:

  -459.670013427734
   459.670013427734
   1.80000000000000

0 Kudos
mecej4
Honored Contributor III
728 Views

What I tried was the program

program ww
implicit none
real*8 :: KTOFFact       = 1.8
real*8 :: KTOFShift      = 459.67
write(6,*) KTOFShift
write(6,*) KTOFFact
end

which gave the following output when compiled using the 15.0.4.221 compiler with /fpconstant:

   459.670000000000
   1.80000000000000

From your response, I gather that the circumstances when the error occurs are more shrouded.

0 Kudos
Adrian_F_1
Beginner
728 Views

mecej4 wrote:

What I tried was the program

program ww
implicit none
real*8 :: KTOFFact       = 1.8
real*8 :: KTOFShift      = 459.67
write(6,*) KTOFShift
write(6,*) KTOFFact
end

which gave the following output when compiled using the 15.0.4.221 compiler with /fpconstant:

   459.670000000000
   1.80000000000000

From your response, I gather that the circumstances when the error occurs are more shrouded.

I changed the - to a +:

      real*8 :: KTOFShift      = +459.67

and still got:

   459.670013427734
   1.80000000000000

However if I remove the '+' sign it works as you say.  Very odd indeed.

 

0 Kudos
mecej4
Honored Contributor III
728 Views

A different output depending on whether or not a '+' sign is prefixed? Totally unexpected! Perhaps, the promotion of the constant is skipped if either the '+' or the '-' prefix is seen?

0 Kudos
Adrian_F_1
Beginner
728 Views

mecej4 wrote:

A different output depending on whether or not a '+' sign is prefixed? Totally unexpected! Perhaps, the promotion of the constant is skipped if either the '+' or the '-' prefix is seen?

So it seems:

      program ww
      implicit none
      real*8 :: KTOFFact       = 1.8
      real*8 :: KTOFShift      = +459.67
      real*8 :: KTOFShift1     = 459.67
      write(6,*) KTOFFact
      write(6,*) KTOFShift
      write(6,*) KTOFShift1
      end

gives:

   1.80000000000000
   459.670013427734
   459.670000000000

I think you're right.  Adding the '+' or '-' prefix probably makes it a calculation apart from a raw constant.  However I have always expected /fpconstant to work when the constants are embedded in a formula, which would obviously include calculations.

Maybe Steve has an answer here as I'm loathed to start adding D0 or _DP to all constants in 400,000 lines of code.

 

0 Kudos
NotThatItMatters
Beginner
728 Views

I must admit, I started adding _DP or the like 9 years ago with my 300K lines, and I have never felt confident enough to let the /fpconstant go.

Oh, well.

0 Kudos
Steven_L_Intel1
Employee
728 Views

We have no plans to "phase out" /fpconstant, but your using it makes your code nonportable so I recommend against it. Yes, the use of the + or - sign in this specific context is what triggers the bug.

0 Kudos
mecej4
Honored Contributor III
728 Views

Adrian F., please see if you can build and use the conversion utility "stod" at ftp://ftp.math.utah.edu/pub/misc/index.html#dtosstod to convert your source code so that the real constants are replaced by double precision versions in standard notation. You need the GNU Flex library, which can be installed inside Cygwin, or in Linux/Unix.

 

0 Kudos
Adrian_F_1
Beginner
728 Views

Thanks but...

ftp://ftp.math.utah.edu/pub/misc/index.html#dtosstod

page not found.

0 Kudos
mecej4
Honored Contributor III
728 Views

Adrian F. wrote:

Thanks but...

ftp://ftp.math.utah.edu/pub/misc/index.html#dtosstod

page not found.

I do not know why your browser had a problem with that URL. I clicked on the link in your reply in Chrome (Windows) and was taken to the page immediately. Try again, using the part of the URL preceding '#', or start with http://www.math.utah.edu/~beebe/software/fortran-tools.html and work your way to the download link, starting at the "dtosstod" entry under "Table of Contents".

Caution: the program "stod" goes beyond converting literal constants. It also converts declarations, references to intrinsic functions, etc.

0 Kudos
Adrian_F_1
Beginner
728 Views

I use Chrome.  Tried in Firefox and IE, both couldn't find it.  Tried without the bit after the #, but all still failed.  Maybe it's a country block?  I'm in UK.

Pity that Fortran doesn't treat real constants as double like C though.

0 Kudos
mecej4
Honored Contributor III
728 Views

Here is the URL for the author's home page: http://www.math.utah.edu/~beebe/ . If you cannot access that, I don't know what to suggest. The software appears to have no distribution restrictions.

0 Kudos
Adrian_F_1
Beginner
728 Views

Thanks I can access that.  However I got as far as: http://www.math.utah.edu/~beebe/software/fortran-tools.html

However when I click on the ftp link it fails.  It might be some ftp restrictions on my side, I will check tomorrow.

0 Kudos
Adrian_F_1
Beginner
727 Views

Tried 3 different browsers on 2 machines, but all failed to find this webpage.  Perhaps you could download it for me and post it somewhere?
 

0 Kudos
Adrian_F_1
Beginner
650 Views

Incidentally it seems ok when in code:

      program ww
      implicit none

      real*8 :: KTOFFact       = 1.8
      real*8 :: KTOFShift      = -459.67
      real*8 :: KTOFShift1     = 459.67d0
      real*8 :: test
      write(6,*) KTOFFact
      write(6,*) KTOFShift
      write(6,*) KTOFShift1

      test = KTOFShift1 - 459.67
      write(6,*) test

      end

   1.80000000000000
  -459.670013427734
   459.670000000000
  0.000000000000000E+000

0 Kudos
Reply