]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/testsuite/gfortran.dg/round_4.f90
Remove obsolete Solaris 9 support
[thirdparty/gcc.git] / gcc / testsuite / gfortran.dg / round_4.f90
CommitLineData
82a4f54c
TB
1! { dg-do run }
2! { dg-add-options ieee }
d9f069ab 3! { dg-skip-if "PR libfortran/58015" { hppa*-*-hpux* } }
82a4f54c
TB
4!
5! PR fortran/35862
6!
7! Test whether I/O rounding works. Uses internally (libgfortran) strtod
8! for the conversion - and sets the CPU rounding mode accordingly.
9!
13b670ac
BE
10! Only few strtod implementations currently support rounding. Therefore
11! we use a heuristic to determine if the rounding support is available.
12! The assumption is that if strtod gives *different* results for up/down
13! rounding, then it will give *correct* results for nearest/zero/up/down
14! rounding too. And that is what is effectively checked.
15!
82a4f54c 16! If it doesn't work on your system, please check whether strtod handles
13b670ac
BE
17! rounding correctly and whether your system is supported in
18! libgfortran/config/fpu*.c
82a4f54c
TB
19!
20! Please only add ... run { target { ! { triplets } } } if it is unfixable
13b670ac 21! on your target - and a note why (strtod has broken rounding support, etc.)
82a4f54c
TB
22!
23program main
24 use iso_fortran_env
25 implicit none
26
27 ! The following uses kinds=10 and 16 if available or
28 ! 8 and 10 - or 8 and 16 - or 4 and 8.
29 integer, parameter :: xp = real_kinds(ubound(real_kinds,dim=1)-1)
30 integer, parameter :: qp = real_kinds(ubound(real_kinds,dim=1))
31
32 real(4) :: r4p, r4m, ref4u, ref4d
33 real(8) :: r8p, r8m, ref8u, ref8d
34 real(xp) :: r10p, r10m, ref10u, ref10d
35 real(qp) :: r16p, r16m, ref16u, ref16d
36 character(len=20) :: str, round
13b670ac
BE
37 logical :: rnd4, rnd8, rnd10, rnd16
38
39 ! Test for which types glibc's strtod function supports rounding
40 str = '0.01 0.01 0.01 0.01'
41 read (str, *, round='up') r4p, r8p, r10p, r16p
42 read (str, *, round='down') r4m, r8m, r10m, r16m
43 rnd4 = r4p /= r4m
44 rnd8 = r8p /= r8m
45 rnd10 = r10p /= r10m
46 rnd16 = r16p /= r16m
47! write (*, *) rnd4, rnd8, rnd10, rnd16
82a4f54c
TB
48
49 ref4u = 0.100000001_4
50 ref8u = 0.10000000000000001_8
51
52 if (xp == 4) then
53 ref10u = 0.100000001_xp
54 elseif (xp == 8) then
55 ref10u = 0.10000000000000001_xp
56 else ! xp == 10
57 ref10u = 0.1000000000000000000014_xp
58 end if
59
60 if (qp == 8) then
61 ref16u = 0.10000000000000001_qp
62 elseif (qp == 10) then
63 ref16u = 0.1000000000000000000014_qp
64 else ! qp == 16
65 ref16u = 0.10000000000000000000000000000000000481_qp
66 end if
67
68 ! ref*d = 9.999999...
69 ref4d = nearest (ref4u, -1.0_4)
70 ref8d = nearest (ref8u, -1.0_8)
71 ref10d = nearest (ref10u, -1.0_xp)
72 ref16d = nearest (ref16u, -1.0_qp)
73
74 round = 'up'
75 call t()
13b670ac
BE
76 if (rnd4 .and. (r4p /= ref4u .or. r4m /= -ref4d)) call abort()
77 if (rnd8 .and. (r8p /= ref8u .or. r8m /= -ref8d)) call abort()
78 if (rnd10 .and. (r10p /= ref10u .or. r10m /= -ref10d)) call abort()
79 if (rnd16 .and. (r16p /= ref16u .or. r16m /= -ref16d)) call abort()
82a4f54c
TB
80
81 round = 'down'
82 call t()
13b670ac
BE
83 if (rnd4 .and. (r4p /= ref4d .or. r4m /= -ref4u)) call abort()
84 if (rnd8 .and. (r8p /= ref8d .or. r8m /= -ref8u)) call abort()
85 if (rnd10 .and. (r10p /= ref10d .or. r10m /= -ref10u)) call abort()
86 if (rnd16 .and. (r16p /= ref16d .or. r16m /= -ref16u)) call abort()
82a4f54c
TB
87
88 round = 'zero'
89 call t()
13b670ac
BE
90 if (rnd4 .and. (r4p /= ref4d .or. r4m /= -ref4d)) call abort()
91 if (rnd8 .and. (r8p /= ref8d .or. r8m /= -ref8d)) call abort()
92 if (rnd10 .and. (r10p /= ref10d .or. r10m /= -ref10d)) call abort()
93 if (rnd16 .and. (r16p /= ref16d .or. r16m /= -ref16d)) call abort()
82a4f54c
TB
94
95 round = 'nearest'
96 call t()
13b670ac
BE
97 if (rnd4 .and. (r4p /= ref4u .or. r4m /= -ref4u)) call abort()
98 if (rnd8 .and. (r8p /= ref8u .or. r8m /= -ref8u)) call abort()
99 if (rnd10 .and. (r10p /= ref10u .or. r10m /= -ref10u)) call abort()
100 if (rnd16 .and. (r16p /= ref16u .or. r16m /= -ref16u)) call abort()
82a4f54c
TB
101
102! Same as nearest (but rounding towards zero if there is a tie
103! [does not apply here])
104 round = 'compatible'
105 call t()
13b670ac
BE
106 if (rnd4 .and. (r4p /= ref4u .or. r4m /= -ref4u)) call abort()
107 if (rnd8 .and. (r8p /= ref8u .or. r8m /= -ref8u)) call abort()
108 if (rnd10 .and. (r10p /= ref10u .or. r10m /= -ref10u)) call abort()
109 if (rnd16 .and. (r16p /= ref16u .or. r16m /= -ref16u)) call abort()
82a4f54c
TB
110contains
111 subroutine t()
112! print *, round
113 str = "0.1 0.1 0.1 0.1"
114 read (str, *,round=round) r4p, r8p, r10p, r16p
115! write (*, '(*(g0:" "))') r4p, r8p, r10p, r16p
116 str = "-0.1 -0.1 -0.1 -0.1"
117 read (str, *,round=round) r4m, r8m, r10m, r16m
118! write (*, *) r4m, r8m, r10m, r16m
119 end subroutine t
120end program main