]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - contrib/netbsd-tests/lib/libc/gen/t_fpsetround.c
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / contrib / netbsd-tests / lib / libc / gen / t_fpsetround.c
1 /* $NetBSD: t_fpsetround.c,v 1.6 2011/10/01 17:46:10 christos Exp $ */
2
3 /*-
4  * Copyright (c) 2011 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Christos Zoulas.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 3. All advertising materials mentioning features or use of this software
19  *    must display the following acknowledgement:
20  *        This product includes software developed by the NetBSD
21  *        Foundation, Inc. and its contributors.
22  * 4. Neither the name of The NetBSD Foundation nor the names of its
23  *    contributors may be used to endorse or promote products derived
24  *    from this software without specific prior written permission.
25  *
26  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36  * POSSIBILITY OF SUCH DAMAGE.
37  */
38 #include <sys/cdefs.h>
39 __RCSID("$NetBSD: t_fpsetround.c,v 1.6 2011/10/01 17:46:10 christos Exp $");
40
41 #include <float.h>
42 #include <math.h>
43 #include <stdlib.h>
44 #include <string.h>
45 #include <stdio.h>
46
47 #include <atf-c.h>
48
49 ATF_TC(fpsetround_basic);
50 ATF_TC_HEAD(fpsetround_basic, tc)
51 {
52
53         atf_tc_set_md_var(tc, "descr",
54             "Minimal testing of fpgetround(3) and fpsetround(3)");
55 }
56
57 #ifdef _FLOAT_IEEE754
58 #include <ieeefp.h>
59
60 static const struct {
61         const char *n;
62         int rm;
63         int rf;
64 } rnd[] = {
65         { "RN", FP_RN, 1 },
66         { "RP", FP_RP, 2 },
67         { "RM", FP_RM, 3 },
68         { "RZ", FP_RZ, 0 },
69
70 };
71
72 static const struct {
73         const char *n;
74         int v[4];
75 } tst[] = {     /*  RN  RP  RM  RZ */
76         {  "1.1", {  1,  1,  2,  1 } },
77         {  "1.5", {  1,  2,  2,  1 } },
78         {  "1.9", {  1,  2,  2,  1 } },
79         {  "2.1", {  2,  2,  3,  2 } },
80         {  "2.5", {  2,  2,  3,  2 } },
81         {  "2.9", {  2,  3,  3,  2 } },
82         { "-1.1", { -1, -1, -1, -2 } },
83         { "-1.5", { -1, -2, -1, -2 } },
84         { "-1.9", { -1, -2, -1, -2 } },
85         { "-2.1", { -2, -2, -2, -3 } },
86         { "-2.5", { -2, -2, -2, -3 } },
87         { "-2.9", { -2, -3, -2, -3 } },
88 };
89
90 static const char *
91 getname(int r)
92 {
93         for (size_t i = 0; i < __arraycount(rnd); i++)
94                 if (rnd[i].rm == r)
95                         return rnd[i].n;
96         return "*unknown*";
97 }
98
99 static void
100 test(int r)
101 {
102         int did = 0;
103         for (size_t i = 0; i < __arraycount(tst); i++) {
104                 double d = strtod(tst[i].n, NULL);
105                 int g = (int)rint(d);
106                 int e = tst[i].v[r];
107                 ATF_CHECK_EQ(g, e);
108                 if (g != e) {
109                         if (!did) {
110                                 fprintf(stderr, "Mode Value Result Expected\n");
111                                 did = 1;
112                         }
113                         fprintf(stderr, "%4.4s %-5.5s %6d %8d\n", rnd[r].n,
114                             tst[i].n, (int)rint(d), tst[i].v[r]);
115                 }
116         }
117 }
118 #endif
119
120
121 ATF_TC_BODY(fpsetround_basic, tc)
122 {
123
124 #ifndef _FLOAT_IEEE754
125         atf_tc_skip("Test not applicable on this architecture.");
126 #else
127         int r;
128
129         ATF_CHECK_EQ(r = fpgetround(), FP_RN);
130         if (FP_RN != r)
131                 fprintf(stderr, "default expected=%s got=%s\n", getname(FP_RN),
132                     getname(r));
133         ATF_CHECK_EQ(FLT_ROUNDS, 1);
134
135         for (size_t i = 0; i < __arraycount(rnd); i++) {
136                 const size_t j = (i + 1) & 3;
137                 const int o = rnd[i].rm;
138                 const int n = rnd[j].rm;
139
140                 ATF_CHECK_EQ(r = fpsetround(n), o);
141                 if (o != r)
142                         fprintf(stderr, "set %s expected=%s got=%s\n",
143                             getname(n), getname(o), getname(r));
144                 ATF_CHECK_EQ(r = fpgetround(), n);
145                 if (n != r)
146                         fprintf(stderr, "get expected=%s got=%s\n", getname(n),
147                             getname(r));
148                 ATF_CHECK_EQ(r = FLT_ROUNDS, rnd[j].rf);
149                 if (r != rnd[j].rf)
150                         fprintf(stderr, "rounds expected=%x got=%x\n",
151                             rnd[j].rf, r);
152                 test(r);
153         }
154 #endif /* _FLOAT_IEEE754 */
155 }
156
157 ATF_TP_ADD_TCS(tp)
158 {
159
160         ATF_TP_ADD_TC(tp, fpsetround_basic);
161
162         return atf_no_error();
163 }