This is the mail archive of the fortran@gcc.gnu.org mailing list for the GNU Fortran project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: single to double conversion


Hello,

Brian Barnes wrote:
> The fix turned out to be declaring every part of the RNG as double
> precision, as the result was being passed from a single precision function
> in the RNG to a double precision variable in the main program.  This
> conversion, which would be implicit and automatically promote single to
> double in g77, does not occur in gfortran and therefore the code did not
> work properly.  No problems in DEC's f90 either.

Could you try the option  -fdefault-real-8 ? This converts all "real"
into "double precision" (on platforms where real are 4 bytes and double
precision 8 bytes)?
That way you have automatically only real(8) and you should have no problem.

I wouldn't be surprised if you pass "-r8" to DEC's f90 compiler.

Note: If you have somewhere "real(4)" rather than "real", this does not
help as this stays with 4byte-precision.

If you really want to mix real(4) with real(8), you need to give the
compiler the chance that it knows what a given external routine expects
and returns. Otherwise if you call an external subroutine (which is also
external if it is in the same file), the compiler does not know whether
a real(4) or a real(8) is requested by that subroutine.
In Fortran 90/95/2003 I would recommend to use modules, interfaces or
"contains" to tell the compiler what you want.


> 1.  Why was the implicit conversion of single to double changed from g77
> to gfortran?  I'm guessing it's strict adherence to the standard?  Is it
> possible to have implicit conversion as a GNU extension or compiler
> option?
To my very little* knowledge it has not changed (the problem remains:
The compiler needs to be told (module, "contains", interface,
"external"), which argument it has too pass to the function, otherwise
it might do the wrong thing).
Did you pass a special option to the DEC and g77 compilers?

(* I never used g77, I started with ifort and Fortran 9x.)


> 2.  Can any real math errors occur in code compiled with gfortran when
> simple math is written out in single precision (or similar things, such as
> the integer multiplication above)?
single precision should work as well as double precision, except that
due to the limited number of significant digits you may loose precision;
depending on your problem, you may also run into under-/overflows.
print *,huge(real4_variable), huge(real8_variable) gives here:
  3.4028235E+38  1.797693134862316E+308
All number crunching programs I know of use by default real(8), although
some offer to use real(4) for less precise and faster calculations.

> 3.  Is it a bug for -Wconversion not to return a warning for code such as:
> program main
> real*8 number,ran_u
> number=ran_u()
> end
> function ran_u()
> ...single precision algorithm...
> ran_u=result
> end

Yes and no. Fortran regards "program ... end program" and "function
ran_u() ... end function" as completely separate, even if they are in
the same file.
I think there exists a bug report (feature request) to catch such
problems if they occur in the same file. Some compilers (such as the
intel compiler) offer an option (ifort: -gen-interfaces; this creates
interface information for compiled fortran files), which also allows to
check such problems, if the routines are in different files.

In your example above the problem is that you tell the compiler to
assume real(8) as return value, however, it returns something different.

In Fortran 90/95/2003 the easiest way is to do the following:

program main
implicit none
real(8) :: number
number = run_u()
CONTAINS ! <---------
function ran_u()
real(4) :: run_u
end function rand_u
end program main ! < --------

That way the compiler knows what kind of real the function returns and
can thus convert the real(8) into real(4) [or with -Wconversion] warn
that you may loose information.

> I also realize the -fdefault-real-8 would have solved my problem, but
> that is not an option I always want to use.
Ok, I missed this when I replies above.
Without such an option, you program only works if "real*8" and "real"
are both 8bytes long (and double precision would be then real*10 or
real*16 or...), which might be the case on some special platforms.

Tobias


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]