2 ! { dg-add-options ieee }
6 ! Test whether I/O rounding works. Uses internally (libgfortran) strtod
7 ! for the conversion - and sets the CPU rounding mode accordingly.
9 ! Only few strtod implementations currently support rounding. Therefore
10 ! we use a heuristic to determine if the rounding support is available.
11 ! The assumption is that if strtod gives *different* results for up/down
12 ! rounding, then it will give *correct* results for nearest/zero/up/down
13 ! rounding too. And that is what is effectively checked.
15 ! If it doesn't work on your system, please check whether strtod handles
16 ! rounding correctly and whether your system is supported in
17 ! libgfortran/config/fpu*.c
19 ! Please only add ... run { target { ! { triplets } } } if it is unfixable
20 ! on your target - and a note why (strtod has broken rounding support, etc.)
26 ! The following uses kinds=10 and 16 if available or
27 ! 8 and 10 - or 8 and 16 - or 4 and 8.
28 integer, parameter :: xp
= real_kinds(ubound(real_kinds
,dim
=1)-1)
29 integer, parameter :: qp
= real_kinds(ubound(real_kinds
,dim
=1))
31 real(4) :: r4p
, r4m
, ref4u
, ref4d
32 real(8) :: r8p
, r8m
, ref8u
, ref8d
33 real(xp
) :: r10p
, r10m
, ref10u
, ref10d
34 real(qp
) :: r16p
, r16m
, ref16u
, ref16d
35 character(len
=20) :: str
, round
36 logical :: rnd4
, rnd8
, rnd10
, rnd16
38 ! Test for which types glibc's strtod function supports rounding
39 str
= '0.01 0.01 0.01 0.01'
40 read (str
, *, round
='up') r4p
, r8p
, r10p
, r16p
41 read (str
, *, round
='down') r4m
, r8m
, r10m
, r16m
46 ! write (*, *) rnd4, rnd8, rnd10, rnd16
49 ref8u
= 0.10000000000000001_8
52 ref10u
= 0.100000001_xp
54 ref10u
= 0.10000000000000001_xp
56 ref10u
= 0.1000000000000000000014_xp
60 ref16u
= 0.10000000000000001_qp
61 elseif (qp
== 10) then
62 ref16u
= 0.1000000000000000000014_qp
64 ref16u
= 0.10000000000000000000000000000000000481_qp
68 ref4d
= nearest (ref4u
, -1.0_4
)
69 ref8d
= nearest (ref8u
, -1.0_8
)
70 ref10d
= nearest (ref10u
, -1.0_xp
)
71 ref16d
= nearest (ref16u
, -1.0_qp
)
75 if (rnd4
.and
. (r4p
/= ref4u
.or
. r4m
/= -ref4d
)) call abort()
76 if (rnd8
.and
. (r8p
/= ref8u
.or
. r8m
/= -ref8d
)) call abort()
77 if (rnd10
.and
. (r10p
/= ref10u
.or
. r10m
/= -ref10d
)) call abort()
78 if (rnd16
.and
. (r16p
/= ref16u
.or
. r16m
/= -ref16d
)) call abort()
82 if (rnd4
.and
. (r4p
/= ref4d
.or
. r4m
/= -ref4u
)) call abort()
83 if (rnd8
.and
. (r8p
/= ref8d
.or
. r8m
/= -ref8u
)) call abort()
84 if (rnd10
.and
. (r10p
/= ref10d
.or
. r10m
/= -ref10u
)) call abort()
85 if (rnd16
.and
. (r16p
/= ref16d
.or
. r16m
/= -ref16u
)) call abort()
89 if (rnd4
.and
. (r4p
/= ref4d
.or
. r4m
/= -ref4d
)) call abort()
90 if (rnd8
.and
. (r8p
/= ref8d
.or
. r8m
/= -ref8d
)) call abort()
91 if (rnd10
.and
. (r10p
/= ref10d
.or
. r10m
/= -ref10d
)) call abort()
92 if (rnd16
.and
. (r16p
/= ref16d
.or
. r16m
/= -ref16d
)) call abort()
96 if (rnd4
.and
. (r4p
/= ref4u
.or
. r4m
/= -ref4u
)) call abort()
97 if (rnd8
.and
. (r8p
/= ref8u
.or
. r8m
/= -ref8u
)) call abort()
98 if (rnd10
.and
. (r10p
/= ref10u
.or
. r10m
/= -ref10u
)) call abort()
99 if (rnd16
.and
. (r16p
/= ref16u
.or
. r16m
/= -ref16u
)) call abort()
101 ! Same as nearest (but rounding towards zero if there is a tie
102 ! [does not apply here])
105 if (rnd4
.and
. (r4p
/= ref4u
.or
. r4m
/= -ref4u
)) call abort()
106 if (rnd8
.and
. (r8p
/= ref8u
.or
. r8m
/= -ref8u
)) call abort()
107 if (rnd10
.and
. (r10p
/= ref10u
.or
. r10m
/= -ref10u
)) call abort()
108 if (rnd16
.and
. (r16p
/= ref16u
.or
. r16m
/= -ref16u
)) call abort()
112 str
= "0.1 0.1 0.1 0.1"
113 read (str
, *,round
=round
) r4p
, r8p
, r10p
, r16p
114 ! write (*, '(*(g0:" "))') r4p, r8p, r10p, r16p
115 str
= "-0.1 -0.1 -0.1 -0.1"
116 read (str
, *,round
=round
) r4m
, r8m
, r10m
, r16m
117 ! write (*, *) r4m, r8m, r10m, r16m