[petsc-dev] fortran literals

Barry Smith bsmith at mcs.anl.gov
Thu Sep 1 15:05:41 CDT 2016


   I didn't have a solution to this

> On Sep 1, 2016, at 2:36 PM, Munson, Todd <tmunson at mcs.anl.gov> wrote:
> 
> 
> 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.

  Does your proposed PetscRealCast() work? Note that for double you shouldn't even need the dble()

  If it does then I can live with it. 

   Yes, quad is a pain but I can live with it as an outlier for now.

> 
> =====
> 
> 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