How do I pass precision using a parameter to variables inside a parameterized data type

I would like the precision of a variable inside a derived data type to be passed using a parameter. How do I do this ?
This is what I tried, but got errors .

program para_derivedtype
  implicit none


  type test(var_pres)
     real(var_pres) :: a,b
  end type test


  integer,parameter :: dp=kind(0.d0)
  type(test(dp)) :: t



  t%a=5.7
  t%b=6.898989

  print *, t%a
  print *, t%b

end program para_derivedtype

Thanks

1 Like

Try to include the kind parameter in the type definition:

  type test(var_pres)
     integer, kind :: var_pres
     real(var_pres) :: a,b
  end type test
2 Likes

This worked for me, Thank you !

Careful. 5.7 and 6.898989 are single precision numbers. You need to use 5.7_dp and 6.898989_dp.

1 Like

Thank you ! Do you know if this eliminates the garbage data in the variables as well ? If not how do I do it ?
For example :
4.90000 becomes 4.900000784456

That is a naive question. You will have to reconcile yourself to peaceful coexistence with what you call “garbage”.

Try to answer the following question for yourself: What is the representation of 1/3 in base-10? What are the representations of 0.1 and 0.1_dp in base-2?

Note, as well, that constants such as 4.9 are single-precision, and 4.9d0 is double- precision. Try the following test:

print *,4.9-4.9d0
end

Another instructive test program:

program fp
   Print '(E20.10,E30.20)',0.1,0.1d0
end program fp

There is a somewhat long but excellent article by D. Goldberg, which is well worth reading by anyone who is undertaking substantial calculations using finite-precision floating point arithmetic on a computer.

2 Likes

9.536743128535363E-008
0.1000000015E+00 0.10000000000000000555E+00
were the outputs I got for both tests

also
1/3 in base 10 is just 0.33333 , is it not ? (The numbers used are one less than the base)
0.1 is 0.1 in base 2
0.1_dp in base 2 will be something crazy since we can’t go over 1

Am I wrong anywhere here ?

The fraction 1/3 cannot be represented as a decimal number with a finite number of digits. In base-3, it would be just 0.1 . The number 0.1 in base-2 would be an exact representation of 1/2 = 0.5 in decimal.

The decimal number 0.1 cannot be expressed exactly in base-2. Its 32-bit representation is Z’3DCCCCCD’, and its 64-bit representation is is Z’3FB999999999999A’, and you can explore this using the online tool at IEEE-754 Floating-Point Conversion from Floating-Point to Hexadecimal . Notice that the last digits differ from the preceding ones because of rounding.

1 Like

Thank you for the extra information, I clearly have stuff to touch up on.

In addition to Goldbergs paper, The Oracle Developer Studio 12.6 Numerical Computation Guide has a lot of useful info on floating point operations and an Appendix that is an “Addendum” to Goldbergs paper that that discusses differences in IEEE 754 implementations. See

Also, does anyone know the status of the Oracle Developer Studio compilers. The last (I presume free) release was 12.6 which was several years ago now. Do you have to buy Oracle hardware now to get their latest compilers?

1 Like

You can still get the 12.6 Oracle Developer Studio for Solaris and Linux, free of charge (registration required).