An alternative method to the method of High Performance Mark is to do use the TL
and TR
position-edit-descriptors. First print the float with Fw.d
, move w positions back, print the integer with padding zeros and width w − d, move d + 1 positions forward.
write (*, '(F6.3,TL6,I2.2,TR4)') f,int(f)
The problem this method and the method of High Performance Mark have is rounding. The following program demonstrates this:
program test_rounding
double precision :: f
f = 6 - 1D-6
! default compiler dependent rounding :: gfortran NEAREST
write (*, '(F6.3,TL6,I2.2,TR4)') f,int(f)
write (*, '(I2.2,F0.3)') int(f), f-int(f)
write (*, '(I2.2,F4.3)') int(f), f-int(f)
! rounding to ZERO
write (*, '(I2.2,RZ,F4.3)') int(f), f-int(f)
write (*, '(RZ,F6.3,TL6,I2.2,TR4)') f,int(f)
end program
05.000 < WRONG
051.000 < VERY WRONG
05**** < EUH
05.999 < OFF BY 0.001
05.999 < OFF BY 0.001
The last method might be of interest, but it is not really the expected value. However, it has the same accuracy.
The following two methods work as expected, but it is required to do manual manipulate the numbers with the respected accuracy. This is not what one would expect:
program test_rounding
double precision :: f
f = 6 - 1D-6
! manual manipulation
write (*,'(I2.2,".",I3.3)') nint(f*1D3)/1000, mod(nint(f*1D3),1000)
write (*,'(F6.3,TL6,I2.2,TR4)') f,nint(f*1D3)/1000
end program
Both return 06.000