9. Precision
probe has computed in double precision so far. VecFor has the same vector in single, double and quadruple precision; probe measures the edge from p2 to p3, of length
program probe
!< Tutorial, chapter 9: the same edge in single, double and quadruple precision.
use, intrinsic :: iso_fortran_env, only : real128
use penf, only : R4P, R8P, R16P
use vecfor, only : ex_R4P, ey_R4P, ex_R8P, ey_R8P, ex_R16P, ey_R16P, normL2_R4P, vector, vector_R4P, vector_R8P, &
vector_R16P
implicit none
type(vector_R4P) :: a4 ! single precision
type(vector_R8P) :: a8 ! double precision
type(vector_R16P) :: a16 ! quadruple precision, if the library is built for it
type(vector) :: a ! the default: double precision
real(real128) :: l ! the exact length, sqrt(2), to 33 digits
l = sqrt(2._real128)
a4 = ey_R4P - ex_R4P ! each kind has its own versors
a8 = ey_R8P - ex_R8P
a16 = ey_R16P - ex_R16P
print '(A,I3,A,ES10.2)', 'R4P : digits', precision(a4%x), ', error of the length', &
abs(a4%normL2() - l)
print '(A,I3,A,ES10.2)', 'R8P : digits', precision(a8%x), ', error of the length', &
abs(a8%normL2() - l)
print '(A,I3,A,ES10.2)', 'R16P: digits', precision(a16%x), ', error of the length', &
abs(a16%normL2() - l)
print '(A,I3)', 'vector: digits', precision(a%x)
a4 = a4 * 0.1_R8P ! a scalar of another kind is converted to the kind of the vector
print '(A,ES16.8)', 'x of a4 * 0.1 ', a4%x
print '(A,ES16.8)', 'length, function ', normL2_R4P(a4)
a8%x = real(a4%x, R8P) ! from one kind to another: component by component
a8%y = real(a4%y, R8P)
a8%z = real(a4%z, R8P)
print '(A,ES24.16)', 'x of a8 ', a8%x
endprogram probeWith VecFor built as by its FoBiS modes:
$ probe
R4P : digits 6, error of the length 2.42E-08
R8P : digits 15, error of the length 9.67E-17
R16P: digits 15, error of the length 9.67E-17
vector: digits 15
x of a4 * 0.1 -1.00000001E-01
length, function 1.41421363E-01
x of a8 -1.0000000149011612E-01With VecFor built with -DPENF_R16P:
$ probe
R4P : digits 6, error of the length 2.42E-08
R8P : digits 15, error of the length 9.67E-17
R16P: digits 33, error of the length 0.00E+00
vector: digits 15
x of a4 * 0.1 -1.00000001E-01
length, function 1.41421363E-01
x of a8 -1.0000000149011612E-01Three precisions, one module
use vecfor exports a vector type for each real kind of PENF: vector_R4P (single precision), vector_R8P (double) and vector_R16P (quadruple), each with its versors (ex_R4P, ey_R8P, ez_R16P, ...) and its free functions (normL2_R4P, angle_R16P, ...). The type-bound methods and the operators have the same names for every kind: a4%normL2(), a16 .cross. b16. vector is the default kind, double precision, with ex, ey, ez and the unsuffixed functions.
A single precision vector has 6 significant digits: its length is off by
True quadruple precision
vector_R16P is as precise as the kind R16P of PENF, and PENF makes R16P a true quadruple precision kind only when it is compiled with -DPENF_R16P. The FoBiS modes of VecFor do not define it, so in their builds R16P is double precision and vector_R16P has 15 digits, as the first run shows. Built with -DPENF_R16P (library and program alike, see Precision and kinds), vector_R16P has 33 digits and the length is exact to all the digits printed, as the second run shows. The reference here is real128 of iso_fortran_env, which does not depend on PENF.
Scalars of other kinds, vectors of other kinds
A scalar of any kind can meet a vector of any kind: a4 * 0.1_R8P converts 0.1 to single precision first, and the result is a single precision vector, with the error of single precision (-1.00000001E-01).
Two vectors of different kinds cannot: there is no a4 + a8, nor a8 = a4. Convert component by component, with real(a4%x, R8P): the result carries the error of the single precision value (-1.0000000149011612E-01), digits cannot be recovered. Note that vector and vector_R8P are two different types too, although both are double precision: vector comes from its own module, so a vector_R8P is not assigned to a vector either (see Vectors of each precision).
What you learned
vector_R4P, vector_R8P, vector_R16P and their versors and functions; true quadruple precision with -DPENF_R16P; scalars of any kind, vectors converted by components. Reference: Precision and kinds.
Next: 10. Printing and files.