I’m doing some digging and this is confusing me even further:
module kinds    
    implicit none
    
    !> Single precision real numbers, 6 digits, range 10⁻³⁷ to 10³⁷-1; 32 bits
    integer, parameter :: sp = selected_real_kind(6, 37)
    !> Double precision real numbers, 15 digits, range 10⁻³⁰⁷ to 10³⁰⁷-1; 64 bits
    integer, parameter :: dp = selected_real_kind(15, 307)
    !> Quadruple precision real numbers, 33 digits, range 10⁻⁴⁹³¹ to 10⁴⁹³¹-1; 128 bits
    integer, parameter :: qp = selected_real_kind(33, 4931)
    !> Char length for integers, range -2⁷ to 2⁷-1; 8 bits
    integer, parameter :: i1 = selected_int_kind(2)
    !> Short length for integers, range -2¹⁵ to 2¹⁵-1; 16 bits
    integer, parameter :: i2 = selected_int_kind(4)
    !> Length of default integers, range -2³¹ to 2³¹-1; 32 bits
    integer, parameter :: i4 = selected_int_kind(9)
    !> Long length for integers, range -2⁶³ to 2⁶³-1; 64 bits
    integer, parameter :: i8 = selected_int_kind(18)
    integer, parameter :: wp = dp
end module kinds
program test_kinds
    use kinds
    implicit none
    real(dp) :: x
    real(dp) :: y1, y2, y3, y4, y5, y6, y7, y8, y9, y10
    x = 0.5_dp
    ! y1 shows a loss of precision
    y1 = (2 * x**5) ** (1.0 / 3.0) + 3*exp(x*2)
    y2 = (2 * x**5) ** (1.0_dp / 3.0_dp) + 3*exp(x*2)
    y3 = (2.0_dp * x**5.0_dp) ** (1.0_dp/3.0_dp) + 3.0_dp*exp(x*2.0_dp)
    ! y4, y5 and y6 give me the same values
    y4 = 1 + y3
    y5 = 1.0 + y3
    y6 = 1.0_dp + y3
    ! y7 and y8 also give me the same values
    y7 = 0.5 + y3
    y8 = 0.5_dp + y3
    ! y9 loses some digits
    y9 = 0.325 + y3
    y10 = 0.325_dp + y3
    write(*,*) 'y1 = ', y1
    write(*,*) 'y2 = ', y2
    write(*,*) 'y3 = ', y3
    write(*,*) 'y4 = ', y4
    write(*,*) 'y5 = ', y5
    write(*,*) 'y6 = ', y6
    write(*,*) 'y7 = ', y7
    write(*,*) 'y8 = ', y8
    write(*,*) 'y9 = ', y9
    write(*,*) 'y10 = ', y10
end program
In this example, the compiler (gfortran 14.2.1) has issues with the (1.0 / 3.0) division at y1. But it seems unnecessary to specify _dp to the rest of the numbers in the formula (in summary, y2 gives me the same result as y3).
So I’ve tried some random tests. summing 1, 1.0 or 1.0_dp gives me the same result up until the 16th decimal. Summing 0.5 or 0.5_dp also gives me the same result. However, summing up a broken real such as 0.325 doesn’t give me the same result as 0.325_dp.
I’m probably going to add _dp to anything just in case, but is there any logic to the kind conversions?