The 'correct' interpretation of intrinsic DBLE

Steve Kargl sgk@troutmask.apl.washington.edu
Wed Dec 21 20:05:00 GMT 2011


On Wed, Dec 21, 2011 at 01:45:23PM -0500, John L. Papp wrote:
> 
> With the new quad precision in the latest gcc releases, what is the 
> 'correct' interpretation of the intrinsic DBLE function?  Under previous 
> versions, a kind=4 or kind=8 sent to DBLE would always return kind=8.  
> With the new quad precision, a kind=8 becomes a kind=16 even if 
> -fdefault-real-8 and/or -fdefault-double-8 are set at compile time.  I 
> was using DBLE to always export variables in the same kind=8 precision 
> regardless of what the intrinsic precision was either explicitly defined 
> or through compile flags.  With quad precision, this fails.  Should 
> there be a standard to DBLE, maybe even an addition of intrinsic QUAD, 
> or is the strict interpretation of DBLE is that it always doubles the 
> precision of the variable up to the highest possible, e.g., kind=2 
> becomes kind=4, kind=4 becomes kind=8, kind=8 becomes kind=16, kind=16 
> becomes kind=32, etc?  In the latter case, the definition of DBLE(A) 
> should be changed to "Converts A to double the original precision real 
> type" not "Converts A to double precision real type".
> 

Instead of guess what DBLE() does, you can actually test it.


   real x
   double precision y
   x = 1. / 3.
   y = x
   print *, dble(x), dble(y)
   end

gfortran -fdump-tree-original -o z foo.f90

(removed some IO related lines)

MAIN__ ()
{
  real(kind=4) x;
  real(kind=8) y;

  x = 3.333333432674407958984375e-1;
  y = (real(kind=8)) x;
  {
    {
      real(kind=8) D.1839;

      D.1839 = (real(kind=8)) x;
      _gfortran_transfer_real_write (&dt_parm.0, &D.1839, 8);
    }
    {
      real(kind=8) D.1840;

      D.1840 = y;
      _gfortran_transfer_real_write (&dt_parm.0, &D.1840, 8);
    }
  }
}

gfortran -fdump-tree-original -fdefault-real-8 -o z foo.f90

MAIN__ ()
{
  real(kind=8) x;
  real(kind=16) y;

  x = 3.33333333333333314829616256247390992939472198486328125e-1;
  y = (real(kind=16)) x;
  {

    {
      real(kind=16) D.1839;

      D.1839 = (real(kind=16)) x;
      _gfortran_transfer_real128_write (&dt_parm.0, &D.1839, 16);
    }
    {
      real(kind=16) D.1840;

      D.1840 = y;
      _gfortran_transfer_real128_write (&dt_parm.0, &D.1840, 16);
    }
  }
}

So, DBLE() does exactly what I told the compiler to do.  Without
the -fdefault-real-8 option, gfortran's default real kind is 
REAL(4) and DBLE() yields a REAL(8) for both REAL(4) and a
REAL(8) input.  With the -fdefault-real-8 option, gfortran's
default real kind is REAL(8) and DOUBLE PRECISION is by
definition REAL(16).  DBLE() now yields a REAL(16) quantity
for either REAL(8) or REAL(16) input.

-- 
Steve



More information about the Fortran mailing list