Reputation: 111
I'm translating a code from Fortran. I get a weird behavior during assignment. I know that adding the code could be very helpful but I can't add the exact code (I'm not authorized) and I was not successful to replicate it.
The lines are the following (qk was predefined and qk1 was not):
print*,"qk",qk
print*,"qk1",qk1
QK1=QK
print*,"qk",qk
print*,"qk1",qk1
and I get these values printed:
qk 21909779.000000000
qk1 6.44842193E+32
qk 21909779.000000000
qk1 21909780.0
The point is that I would expect to get qk1 equal to qk... why are they different? When I try to replicate it, obviously I get the same values printed.
Since I didn't add the code I do not expect a precise answer... does anyone have any idea about what to check?
Upvotes: 1
Views: 323
Reputation: 7432
The reason is that as indicated in the comments qk is single precision, qk1 double, and at the values required the spacing between single precision reals is 2:
Program one_out
Use, Intrinsic :: iso_fortran_env, Only : real32, real64
Implicit None
Real( real64 ) :: qk64
Real( real32 ) :: qk32
qk64 = 21909779.0_real64
qk32 = qk64
Write( *, * ) 'qk64 = ', qk64
Write( *, * ) 'qk32 = ', qk32
Write( *, * ) '64 spacing ', Spacing( qk64 )
Write( *, * ) '32 spacing ', Spacing( qk32 )
End Program one_out
ian@eris:~/work/stack$ gfortran -Wall -Wextra -fcheck=all -std=f2008 one_out.f90
one_out.f90:11:9:
qk32 = qk64
1
Warning: Possible change of value in conversion from REAL(8) to REAL(4) at (1) [-Wconversion]
ian@eris:~/work/stack$ ./a.out
qk64 = 21909779.000000000
qk32 = 21909780.0
64 spacing 3.7252902984619141E-009
32 spacing 2.00000000
The most important lesson here is always, always use Implicit None - and the second is that compiler warning are useful, turn them on and work out what they mean!
Upvotes: 6