|
forums.silverfrost.com Welcome to the Silverfrost forums
|
View previous topic :: View next topic |
Author |
Message |
JohnCampbell
Joined: 16 Feb 2006 Posts: 2580 Location: Sydney
|
Posted: Sun Nov 19, 2017 6:01 am Post subject: |
|
|
John,
The Fortran 90 standard says that you can't.
You could provide such an option, but it would not be portable and would be a bad approach for maintaining the code.
It is all a bit ridiculous. consider the following example:
Code: | Real*8 s,x
integer i
s = 0 ; x = 0.1
do i = 1,10
s = s+x
end do
write (*,*) s
s = 0 ; x = 0.1d0
do i = 1,10
s = s+x
end do
write (*,*) s
end |
Just looking at the code, does not scream out a precision problem, but 0.1 does round to only 7 figures of accuracy, while with Dan's example you can see that more than 7 figures are implied. |
|
Back to top |
|
|
LitusSaxonicum
Joined: 23 Aug 2005 Posts: 2393 Location: Yateley, Hants, UK
|
Posted: Sun Nov 19, 2017 1:42 pm Post subject: |
|
|
Come on guys, be sensible. The default precision for a REAL constant is the default REAL type, which is REAL*4. There's no such thing as a DOUBLE PRECISION constant without the D part.
If you want to make the default for variables AND constants REAL*8, then you use the DREAL option in an OPTION statement.
It isn't a problem, the former is part of Fortran, the latter is part of FTN95. The selection of REAL*4 to be the default real precision is the fault of computer designers: on the UK-designed systems it was REAL*6 (2 x 24-bit words) before that line of thinking was forced out of the market.
The associated problem is that REAL*4 isn't much use for anything that is calculated, and often isn't for anything that is input as data. As an example, consider ground coordinates that need to be specified in mm on a national coordinate system. REAL*4 is OK in the SW of England (a small country) but coordinates become rounded as one passes Salford, and totally inaccurate in Scotland! However, for coordinates of points on a a car, they can be specified in hundreds of a mm with REAL*4. But for my purposes, REAL*4 is usually pointless.
It strikes me that if REAL*4 and INTEGER*4 are the defaults for 32-bit computing (where addressing is via INTEGER*4 length addresses), the REAL*8 and INTEGER*8 should be the defaults for 64-bit computing, even though one then has the problem that DOUBLE PRECISION ought to be 128 bits, and the x86 cpus don't seem to have got to that.
In any case, it seems to me that the OPTIONS statement needs the possibility of an INTx to go with INTL and INTS (perhaps there is, I haven't looked).
Eddie |
|
Back to top |
|
|
JohnCampbell
Joined: 16 Feb 2006 Posts: 2580 Location: Sydney
|
Posted: Mon Nov 20, 2017 1:04 am Post subject: |
|
|
Eddie,
You may be correct. The problem is the FTN compilers would treat the following differently to F90 (and I suspect F77)
Code: | real*8 x
x = 1.83932434324
x = 0.1 |
In both cases, the old compiler's interpretation of the constant would have retained real*8 precision.
This is in the past, so my memory may be failing, but when the Fortran standard required these constants to be stored as real*4, there was a loss of accuracy in a number of programs when converted from FTN to F77. The loss of precision reinforced the view that the newer compiler was not as good as the old one, as it generated less accurate calculations in benchmark comparisons. We've all been there !!
There was another significant event when programs lost precision and that was when real*10 registers disappeared, so again upgrading programs produced an increase in calculated round-off error. |
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 8012 Location: Salford, UK
|
Posted: Mon Nov 20, 2017 10:10 am Post subject: |
|
|
Yes. The quick and easy way is to use /DREAL on the FTN95 command line and this feature was ported from FTN77. |
|
Back to top |
|
|
LitusSaxonicum
Joined: 23 Aug 2005 Posts: 2393 Location: Yateley, Hants, UK
|
Posted: Mon Nov 20, 2017 12:44 pm Post subject: |
|
|
It looks to me that /DREAL is the sensible way to go, as it basically says that REAL is REAL*8, and that DOUBLE PRECISION means the same as REAL. This is fine by me, as I don''t have any use for REAL*16 - if REAL*8 isn't enough, then I would look for a different algorithm. (REAL*16 being DOUBLE PRECISION if REAL*8 is the default REAL).
The compiler can't be a mind-reader, but it does seem logical that the assumed intent of a programmer assigning a more precise than REAL*4 constant to a REAL*8 variable should imply that it is a REAL*8 constant, standard conforming or not, so it depends on whether one wants strictness - which is available with /ISO - or a bit of mind-reading.
Whether the telepathic version should be implemented, it would be consistent wit the treatment of INTEGET constants - see FTN95.CHM description of INTS - which sets integer constants to INTEGER*2 UNLESS they exceed the range for INTEGER*2. The compiler options section notes that /DEFREAL_KIND behaves unlike DEFINT_KIND.
Incidentally, with the Win32 version, there is an /XREAL as well.
While one loses x87 80-bit registers and precision to use SSE etc, this is how Intel designed it, and as most processors are used for Facebook or downloading porn, arithmetic precision is presumably not high on their list of priorities.
Eddie |
|
Back to top |
|
|
DanRRight
Joined: 10 Mar 2008 Posts: 2864 Location: South Pole, Antarctica
|
Posted: Mon Nov 27, 2017 6:35 am Post subject: |
|
|
Leaving aside a hack with /DREAL or OPTIONS(DOUBLE PRECISION) which has little chance to be a common practice in the future I see no reason that in the code
Code: | real*8 X, Y
X=3.4567890123456
Y=3 |
value X was cut to real*4 despite twice was mentioned it has to be real*8 while Y when assigned an INTEGER value got king's treatment and got real*8 precision Y=3.000000000000000E+00. Why at least not the same absurdous real*4? Good that at least compiler now points at this contradiction. Again, I'd consider this specific case an error. |
|
Back to top |
|
|
mecej4
Joined: 31 Oct 2006 Posts: 1896
|
Posted: Mon Nov 27, 2017 11:19 am Post subject: Re: |
|
|
DanRRight wrote: | ... Y when assigned an INTEGER value got king's treatment and got real*8 precision Y=3.000000000000000E+00. Why at least not the same absurdous real*4? |
If you set Y = an integer expression, and the value of that expression lies between -(2^24 - 1) and (2^24-1), 24 bits are sufficient to store the expression without error. Such numbers get "king's treatment". Integers larger in absolute value than these get "queen's treatment", i.e., are subject to chopping or rounding.
A slight variation of your code may help you see things better:
Code: | real*8 X
X=3/4
print *, X
|
If you feel up to it, you may even try
Code: | real*8 X
X='3/4'
print *, X
|
|
|
Back to top |
|
|
DanRRight
Joined: 10 Mar 2008 Posts: 2864 Location: South Pole, Antarctica
|
Posted: Mon Nov 27, 2017 6:34 pm Post subject: |
|
|
Yes, while integers get royal treatment, the obvious real*8 number gets unimaginable: the highway robbery treatment stripping it from extra digits. I have no clue how this got into the Standard. |
|
Back to top |
|
|
JohnCampbell
Joined: 16 Feb 2006 Posts: 2580 Location: Sydney
|
Posted: Tue Nov 28, 2017 9:31 am Post subject: |
|
|
I agree with Dan,
If you coded "X=3.4567890123456", it is very "harsh" of the compiler to strip it to a real*4 constant, but that is what was defined and caused a few unnecessary problems.
There is the case of what to do with SIN ( 3.4567890123456 ) or my_function ( 3.4567890123456 ), which is more of a problem.
The example "real*8 X ; X = 0.6" was also a problem for the unwary, as these types of constants often occurred in FE coding when converting from CDC to mini. F77 devilry !!
Then they introduced object oriented programming as that was supposed to lead to fewer coding errors !! |
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 8012 Location: Salford, UK
|
Posted: Mon Nov 05, 2018 11:41 am Post subject: |
|
|
A new option [fmt=<format_specifier>] has been added to %rf in order to provide program control of the displayed REAL value. The <format_specifier> is analogous to one of %wf, %we and %wg. For example %rf[fmt=0.4e] is equivalent to %0.4we. In other words, we simply omit the '%' and the 'w'. The result in this case is an exponent form with 4 decimal places and 5 significant figures. See the help file on %wf etc. for detailed information on how to write the <format_specifier>.
Here is a simple example:
Code: | program rf
integer k,iw,winio@
real*8 v
v = 1.234567
k = 6
iw = winio@("%co[check_on_focus_loss]&")
iw = winio@("%rf[fmt=0.4e]&",v)
iw = winio@("%ff%nl&")
iw = winio@("%rd&",k)
iw = winio@("%ff%nl&")
iw = winio@("%`rf",v)
end |
And here is a link to new DLLs to try this out...
https://www.dropbox.com/s/xabtjc3cyshi922/newDLLs26.zip?dl=0 |
|
Back to top |
|
|
JohnCampbell
Joined: 16 Feb 2006 Posts: 2580 Location: Sydney
|
Posted: Wed Nov 07, 2018 5:15 am Post subject: |
|
|
Answer to John S:
Code: | ! Example to show real constants not provided in F90+
! similar for 0.1 shows errors,
! but 0.5 or 0.25 are same value for 0.5e0 or 0.5d0
!
real*8 x,y,z,a
x = 0.6 ! F77 would provide a r*8 constant, F90 provides r*4
y = 0.6d0
z = 0.6e0
a = 0.1d0
a = 6*a ! round off difference
write (*,*) 'x = 0.6 ',x
write (*,*) 'y = 0.6d0',y
write (*,*) 'z = 0.6e0',z
write (*,*) 'x-y = ',x-y
write (*,*) 'a = 6*0.1d0',a
write (*,*) 'y-a = ',y-a
end |
What would %rf do with 0.6 ?
I suspect 0.6d0. |
|
Back to top |
|
|
mecej4
Joined: 31 Oct 2006 Posts: 1896
|
Posted: Wed Nov 07, 2018 2:40 pm Post subject: |
|
|
John C.: I realise that the comment on the first executable statement of your illustrative code may be based on a vague recollection, but I do not know if you actually had a Fortran-77 compiler that treated the constant as a double precision constant. If you can name that compiler, and that compiler did that without any options such as /DREAL, that would be interesting, because the Fortran 77 Standard says ( https://www.fortran.com/F77_std/rjcnf0001-sh-4.html#sh-4.2.1 ):
Quote: | 4.2.1 Data Type of a Constant.
The form of the string representing a constant specifies both its value and data type. |
We may critique the rules of the language, and many of us often are puzzled by why some such behaviour was built into the standard. Indeed, I have often wished for a codicil/commentary on the Fortran Standard that provides background and explanation of why and how such features were chosen. Nevertheless, an imperfect standard is far better to have than no standard.
The Salford/Silverfrost FTN77 compiler gives the same output as FTN95 for your test program. |
|
Back to top |
|
|
JohnCampbell
Joined: 16 Feb 2006 Posts: 2580 Location: Sydney
|
Posted: Thu Nov 08, 2018 11:11 am Post subject: |
|
|
Lahey Fortran 95 documentation does refer to this problem.
I recall that Lahey F77 did automatically upgrade constants to double precision, such as " x = 0.6 "
Lahey/Fujitsu Fortran 95 Language Reference :Revision D,
Appendix A : Fortran 77 Compatibility states:
"Standard Fortran 90 is a superset of standard Fortran 77 and a standard-conforming Fortran 77 program will compile properly under Fortran 90. There are, however, some situations in which the program�s interpretation may differ.
� Fortran 77 permitted a processor to supply more precision derived from a REAL constant than can be contained in a REAL datum when the constant is used to initialize a DOUBLE PRECISION data object in a DATA statement. Fortran 90 does not permit this option."
I have experienced the changes to the precision of constants in old code. It has been a significant annoyance when checking transferring code to newer compilers. This problem also was mitigated when transferring from CDC to mini, with constants for REAL*8 being upgraded. Pr1me FTN compiler also provided this support.
( The other significant issue was the loss of 80 bit registers when moving to SSE vector instructions ) |
|
Back to top |
|
|
mecej4
Joined: 31 Oct 2006 Posts: 1896
|
Posted: Thu Nov 08, 2018 1:29 pm Post subject: |
|
|
John, there is no DATA statement in your example code ( http://forums.silverfrost.com/posting.php?mode=quote&p=25703 ), so the Lahey extension (of considering a constant to be DOUBLE PRECISION based on the number of digits in the mantissa being sufficiently large, with or without a "Dnn" exponent field) would not apply. |
|
Back to top |
|
|
JohnCampbell
Joined: 16 Feb 2006 Posts: 2580 Location: Sydney
|
Posted: Thu Nov 08, 2018 1:47 pm Post subject: |
|
|
My recollection is that the increased precision of constants extended to statements like " x = 0.6".
There was support from the mini computer compiler writers to address the precision problems when using double precision/real*8, as a lot of their market was from users of CDC developed software, which they needed to prove could run on their mini. This issue became more significant when moving to F95, which effectively banned this feature.
I am surprised that the Silverfrost F77 doesn't show this feature.
I have tried unsuccessfully to find my 16-bit and 32-bit F77 compilers or documentation. ( which was probably paper copies only )
This is of historical interest only, as the Fortran standard has long been fixed in this approach (nearly 30 years!), requiring precision to now be appropriately addressed. |
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|