- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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?
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
@avinashs,
.. the value assigned by Fortran when read from the file is x = 50.8002001953125 ..
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>
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page