[petsc-dev] fortran literals
Munson, Todd
tmunson at mcs.anl.gov
Thu Sep 1 14:36:52 CDT 2016
Dear petsc developers,
Please do not get too mad at me...
I have a C and Fortran test example that should be exactly the same
problem. The numerical methods, however, produce different results.
I traced this back to the literals used to define constants in the
test Fortran problem. C defaults to double, while Fortran defaults
to single for literals.
What is the correct PETSc way to define literals in Fortran that works
across single and double installations (as well as complex and real)
so that I get the same behavior? PETSc does not appear to define a
macro for this.
I'd like to be able to do something like the following in Fortran:
PetscReal c
c = PetscRealCast(5.78D0)
where PetscRealCast is real() for single precision and dble()
for double precision. Without the cast, you would get all
kinds of warnings of the form "change of value in
conversion" for a single precision installation.
This macro should work for real numbers (not sure about complex as
real() is overloaded as the real part of a complex number), avoids
generating warnings for single and double installs, and produces
the same output for the C and Fortran code.
=====
The followup question is then, how do I make this work correctly for
__float128? In C, I would need to declare the literals using the Q
(e.g. 5.78Q) and then cast to the actual PetscReal type. Without
the Q, the __float128 constant would be initialized to the double
version of 5.78 and only correct to 16 digits.
But is the Q suffix portable? If not, is there portable macro magic
to get full precision constants for single, double, and
quad installs?
Or is the support for __float128 just going to be flakey?
Other than the examples, the biggest place I can see where __float128 may not be
supported correctly is the ts methods where, ts/impls/rosw/rosw.c for example,
defines a ton of constants, many with a very large number of digits, but all
of them are truncated to double precision and the extra digits are thrown
away because of the lack of a Q at the end of the constant, even when
assigned to __float128 variables.
Most others are okay because they are exactly representable, but you can
find constants like 0.7 in few other places.
=====
Note: I already get warnings about using 5.78Q0 in gfortran when declaring
real(16), as its an "extension".
Things get more complicated if you allow people to muck with compiler options
like the gfortran -fdefault-real-8, but maybe we should just call that a
user problem.
Thanks, Todd.
More information about the petsc-dev
mailing list