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

Use of the Intel Fortan compilation option /real-size:64

avinashs
New Contributor I
526 Views

I a number stored in a text file as 50.8, but the value assigned by Fortran when read from the file is x = 50.8002001953125. Is there a way around this problem? Will the compilation option /real-size:64 prevent the noise artificially introduced into the variable?

0 Kudos
4 Replies
Steve_Lionel
Honored Contributor III
513 Views

It's not "noise" - it's that 50.8 cannot be exactly represented in a binary floating-point format. In single-precision it is hex 424B3333.

Double-precision will get you a bit closer - the hex form is 4049666666666666 but the decimal form is 50.79999999999999716.

 
0 Kudos
Arjen_Markus
Honored Contributor I
491 Views

Compare it to representing 1/3 as a decimal number: 1/3 is (approximately) 0.3333333... The reason you can represent 508/10 in a decimal form with a finite number of decimals is that the denominator only contains the same factors 2 and 5 as the radix 10 of the decimal system. In the same way 1/2, 1/8, 1/1024 or 1/625 are representable via a finite number of decimals.

The binary representation used by most computers only contains the factor 2.

0 Kudos
mecej4
Honored Contributor III
484 Views

Avinash,

Here is a short program to reinforce what FF and Arjen have explained. Compile and run, and explain the result that is printed. Change "REAL" to "DOUBLE PRECISION", and repeat.

On a hypothetical CPU that used 3 as the base of the number system, what would the answer have been?

program fpe
   real :: x = 4
   print *,1-(x/3-1)*3
end program fpe

 

0 Kudos
FortranFan
Honored Contributor II
508 Views

 

@avinashs,
.. the value assigned by Fortran when read from the file is x = 50.8002001953125 ..

 

 

@avinashs ,

You would have noticed the above the difference is way too high with any of the usual binary floating-point representation aspects; any number of tools online can show you that with the binary (or hex) representation of the constant.

Under the circumstances, please always consider a minimal working example you can share to illustrate the problem - chances are rather high you will figure out the issue and the solution yourself in the process, thereby empowering you considerably. 

You will note there is little the readers can do otherwise to really help, for they will be left to wonder what may be going on as you can see below:

datafile: "x.dat"

 

50.8

 

Fortran code: "p.f90"

 

   character(len=*), parameter :: fmtg = "(g0,1x,1pg23.16)" 
   character(len=*), parameter :: fmth = "(g0,1x,z0)" 
   blk1: block
      integer, parameter :: WP = selected_real_kind( p=6 )
      real(WP) :: x
      integer :: lun
      print *, "Block 1: with decimal precision of ", precision(x)
      open( newunit=lun, file="x.dat", status="old", form="formatted" )
      read( lun, fmt=* ) x
      print fmtg, "x =     ", x
      print fmth, "x(hex): ", x
      close( lun )
   end block blk1
   print *
   blk2: block
      integer, parameter :: WP = selected_real_kind( p=12 )
      real(WP) :: x
      integer :: lun
      print *, "Block 2: with decimal precision of ", precision(x)
      open( newunit=lun, file="x.dat", status="old", form="formatted" )
      read( lun, fmt=* ) x
      print fmtg, "x =     ", x
      print fmth, "x(hex): ", x
      close( lun )
   end block blk2
end

 

Program using Intel Fortran:

 

C:\Temp>ifort /standard-semantics p.f90
Intel(R) Fortran Intel(R) 64 Compiler Classic for applications running on Intel(R) 64, Version 2021.1.2 Build 20201208_000000
Copyright (C) 1985-2020 Intel Corporation.  All rights reserved.

Microsoft (R) Incremental Linker Version 14.26.28806.0
Copyright (C) Microsoft Corporation.  All rights reserved.

-out:p.exe
-subsystem:console
p.obj

C:\Temp>p.exe
 Block 1: with decimal precision of  6
x =        50.79999923706055
x(hex):  424B3333

 Block 2: with decimal precision of  15
x =        50.80000000000000
x(hex):  4049666666666666

C:\Temp>

 

 

0 Kudos
Reply