Compile time detection of extended-double or quad precision

Thank you all for the proposed solutions, piece by piece I’ve constructed something that works (with an implicit assumption that the default double precision has less than 18 decimal digits of precision).

! has_quad.f90
program main

    implicit none

    ! Default calculation precision
    integer, parameter :: dp = kind(1.0d0)

    ! 1) Check for extended double precision
    integer, parameter :: xdp = merge(-1,selected_real_kind(18), &
        selected_real_kind(18) == selected_real_kind(33))
    logical, parameter :: has_xdp = xdp > 0

    ! 2) Check for true quadruple precision
    integer, parameter :: qp = selected_real_kind(33)
    logical, parameter :: has_qp = qp > 0

    ! 2) Assign speculative higher precision
    integer, parameter :: hp = merge(xdp,merge(qp,-1,has_qp),has_xdp)
    logical, parameter :: has_hp = hp > 0
    
    ! 3) Assign work precision; if higher precision not available, 
    !    fall back to default
    integer, parameter :: wp = merge(hp,dp,has_hp)

    real(dp) :: a(100), asum
    integer :: i

    a = [(i,i=1,100)]

    if (wp == dp) then
        ! work precision equals default, so 
        ! use custom double-double instead
        error stop "Not implemented."
    else
        ! use the higher precision
        asum = real(sum(real(a,wp)),dp)
    endif
    print *, wp, asum

end program main
$ ifx -warn all has_quad_v2.f90 
$ ./a.out
          16   5050.00000000000     
$ gfortran -Wall has_quad_v2.f90 
$ ./a.out
          10   5050.0000000000000     
$ nvfortran has_quad_v2.f90 
$ ./a.out
ERROR STOP Not implemented.

4 Likes