1*11be35a1SLionel Sambuc /* $NetBSD: t_fpclassify.c,v 1.3 2011/10/01 21:47:08 christos Exp $ */
2*11be35a1SLionel Sambuc
3*11be35a1SLionel Sambuc /*-
4*11be35a1SLionel Sambuc * Copyright (c) 2011 The NetBSD Foundation, Inc.
5*11be35a1SLionel Sambuc * All rights reserved.
6*11be35a1SLionel Sambuc *
7*11be35a1SLionel Sambuc * Redistribution and use in source and binary forms, with or without
8*11be35a1SLionel Sambuc * modification, are permitted provided that the following conditions
9*11be35a1SLionel Sambuc * are met:
10*11be35a1SLionel Sambuc * 1. Redistributions of source code must retain the above copyright
11*11be35a1SLionel Sambuc * notice, this list of conditions and the following disclaimer.
12*11be35a1SLionel Sambuc * 2. Redistributions in binary form must reproduce the above copyright
13*11be35a1SLionel Sambuc * notice, this list of conditions and the following disclaimer in the
14*11be35a1SLionel Sambuc * documentation and/or other materials provided with the distribution.
15*11be35a1SLionel Sambuc *
16*11be35a1SLionel Sambuc * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17*11be35a1SLionel Sambuc * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18*11be35a1SLionel Sambuc * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19*11be35a1SLionel Sambuc * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20*11be35a1SLionel Sambuc * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21*11be35a1SLionel Sambuc * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22*11be35a1SLionel Sambuc * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23*11be35a1SLionel Sambuc * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24*11be35a1SLionel Sambuc * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25*11be35a1SLionel Sambuc * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26*11be35a1SLionel Sambuc * POSSIBILITY OF SUCH DAMAGE.
27*11be35a1SLionel Sambuc */
28*11be35a1SLionel Sambuc
29*11be35a1SLionel Sambuc #include <atf-c.h>
30*11be35a1SLionel Sambuc
31*11be35a1SLionel Sambuc #include <float.h>
32*11be35a1SLionel Sambuc #include <math.h>
33*11be35a1SLionel Sambuc #include <stdio.h>
34*11be35a1SLionel Sambuc #include <string.h>
35*11be35a1SLionel Sambuc
36*11be35a1SLionel Sambuc #ifndef _FLOAT_IEEE754
37*11be35a1SLionel Sambuc
38*11be35a1SLionel Sambuc ATF_TC(no_test);
ATF_TC_HEAD(no_test,tc)39*11be35a1SLionel Sambuc ATF_TC_HEAD(no_test, tc)
40*11be35a1SLionel Sambuc {
41*11be35a1SLionel Sambuc atf_tc_set_md_var(tc, "descr", "Dummy test");
42*11be35a1SLionel Sambuc }
43*11be35a1SLionel Sambuc
ATF_TC_BODY(no_test,tc)44*11be35a1SLionel Sambuc ATF_TC_BODY(no_test,tc)
45*11be35a1SLionel Sambuc {
46*11be35a1SLionel Sambuc atf_tc_skip("Test not available on this architecture");
47*11be35a1SLionel Sambuc }
48*11be35a1SLionel Sambuc
49*11be35a1SLionel Sambuc #else /* defined(_FLOAT_IEEE754) */
50*11be35a1SLionel Sambuc
51*11be35a1SLionel Sambuc ATF_TC(fpclassify_float);
ATF_TC_HEAD(fpclassify_float,tc)52*11be35a1SLionel Sambuc ATF_TC_HEAD(fpclassify_float, tc)
53*11be35a1SLionel Sambuc {
54*11be35a1SLionel Sambuc
55*11be35a1SLionel Sambuc atf_tc_set_md_var(tc, "descr", "Test float operations");
56*11be35a1SLionel Sambuc }
57*11be35a1SLionel Sambuc
ATF_TC_BODY(fpclassify_float,tc)58*11be35a1SLionel Sambuc ATF_TC_BODY(fpclassify_float, tc)
59*11be35a1SLionel Sambuc {
60*11be35a1SLionel Sambuc float d0, d1, d2, f, ip;
61*11be35a1SLionel Sambuc int e, i;
62*11be35a1SLionel Sambuc
63*11be35a1SLionel Sambuc d0 = FLT_MIN;
64*11be35a1SLionel Sambuc ATF_REQUIRE_EQ(fpclassify(d0), FP_NORMAL);
65*11be35a1SLionel Sambuc f = frexpf(d0, &e);
66*11be35a1SLionel Sambuc ATF_REQUIRE_EQ(e, FLT_MIN_EXP);
67*11be35a1SLionel Sambuc ATF_REQUIRE_EQ(f, 0.5);
68*11be35a1SLionel Sambuc d1 = d0;
69*11be35a1SLionel Sambuc
70*11be35a1SLionel Sambuc /* shift a "1" bit through the mantissa (skip the implicit bit) */
71*11be35a1SLionel Sambuc for (i = 1; i < FLT_MANT_DIG; i++) {
72*11be35a1SLionel Sambuc d1 /= 2;
73*11be35a1SLionel Sambuc ATF_REQUIRE_EQ(fpclassify(d1), FP_SUBNORMAL);
74*11be35a1SLionel Sambuc ATF_REQUIRE(d1 > 0 && d1 < d0);
75*11be35a1SLionel Sambuc
76*11be35a1SLionel Sambuc d2 = ldexpf(d0, -i);
77*11be35a1SLionel Sambuc ATF_REQUIRE_EQ(d2, d1);
78*11be35a1SLionel Sambuc
79*11be35a1SLionel Sambuc d2 = modff(d1, &ip);
80*11be35a1SLionel Sambuc ATF_REQUIRE_EQ(d2, d1);
81*11be35a1SLionel Sambuc ATF_REQUIRE_EQ(ip, 0);
82*11be35a1SLionel Sambuc
83*11be35a1SLionel Sambuc f = frexpf(d1, &e);
84*11be35a1SLionel Sambuc ATF_REQUIRE_EQ(e, FLT_MIN_EXP - i);
85*11be35a1SLionel Sambuc ATF_REQUIRE_EQ(f, 0.5);
86*11be35a1SLionel Sambuc }
87*11be35a1SLionel Sambuc
88*11be35a1SLionel Sambuc d1 /= 2;
89*11be35a1SLionel Sambuc ATF_REQUIRE_EQ(fpclassify(d1), FP_ZERO);
90*11be35a1SLionel Sambuc f = frexpf(d1, &e);
91*11be35a1SLionel Sambuc ATF_REQUIRE_EQ(e, 0);
92*11be35a1SLionel Sambuc ATF_REQUIRE_EQ(f, 0);
93*11be35a1SLionel Sambuc }
94*11be35a1SLionel Sambuc
95*11be35a1SLionel Sambuc ATF_TC(fpclassify_double);
ATF_TC_HEAD(fpclassify_double,tc)96*11be35a1SLionel Sambuc ATF_TC_HEAD(fpclassify_double, tc)
97*11be35a1SLionel Sambuc {
98*11be35a1SLionel Sambuc
99*11be35a1SLionel Sambuc atf_tc_set_md_var(tc, "descr", "Test double operations");
100*11be35a1SLionel Sambuc }
101*11be35a1SLionel Sambuc
ATF_TC_BODY(fpclassify_double,tc)102*11be35a1SLionel Sambuc ATF_TC_BODY(fpclassify_double, tc)
103*11be35a1SLionel Sambuc {
104*11be35a1SLionel Sambuc double d0, d1, d2, f, ip;
105*11be35a1SLionel Sambuc int e, i;
106*11be35a1SLionel Sambuc
107*11be35a1SLionel Sambuc d0 = DBL_MIN;
108*11be35a1SLionel Sambuc ATF_REQUIRE_EQ(fpclassify(d0), FP_NORMAL);
109*11be35a1SLionel Sambuc f = frexp(d0, &e);
110*11be35a1SLionel Sambuc ATF_REQUIRE_EQ(e, DBL_MIN_EXP);
111*11be35a1SLionel Sambuc ATF_REQUIRE_EQ(f, 0.5);
112*11be35a1SLionel Sambuc d1 = d0;
113*11be35a1SLionel Sambuc
114*11be35a1SLionel Sambuc /* shift a "1" bit through the mantissa (skip the implicit bit) */
115*11be35a1SLionel Sambuc for (i = 1; i < DBL_MANT_DIG; i++) {
116*11be35a1SLionel Sambuc d1 /= 2;
117*11be35a1SLionel Sambuc ATF_REQUIRE_EQ(fpclassify(d1), FP_SUBNORMAL);
118*11be35a1SLionel Sambuc ATF_REQUIRE(d1 > 0 && d1 < d0);
119*11be35a1SLionel Sambuc
120*11be35a1SLionel Sambuc d2 = ldexp(d0, -i);
121*11be35a1SLionel Sambuc ATF_REQUIRE_EQ(d2, d1);
122*11be35a1SLionel Sambuc
123*11be35a1SLionel Sambuc d2 = modf(d1, &ip);
124*11be35a1SLionel Sambuc ATF_REQUIRE_EQ(d2, d1);
125*11be35a1SLionel Sambuc ATF_REQUIRE_EQ(ip, 0);
126*11be35a1SLionel Sambuc
127*11be35a1SLionel Sambuc f = frexp(d1, &e);
128*11be35a1SLionel Sambuc ATF_REQUIRE_EQ(e, DBL_MIN_EXP - i);
129*11be35a1SLionel Sambuc ATF_REQUIRE_EQ(f, 0.5);
130*11be35a1SLionel Sambuc }
131*11be35a1SLionel Sambuc
132*11be35a1SLionel Sambuc d1 /= 2;
133*11be35a1SLionel Sambuc ATF_REQUIRE_EQ(fpclassify(d1), FP_ZERO);
134*11be35a1SLionel Sambuc f = frexp(d1, &e);
135*11be35a1SLionel Sambuc ATF_REQUIRE_EQ(e, 0);
136*11be35a1SLionel Sambuc ATF_REQUIRE_EQ(f, 0);
137*11be35a1SLionel Sambuc }
138*11be35a1SLionel Sambuc
139*11be35a1SLionel Sambuc /*
140*11be35a1SLionel Sambuc * XXX NetBSD doesn't have long-double flavors of frexp, ldexp, and modf,
141*11be35a1SLionel Sambuc * XXX so this test is disabled.
142*11be35a1SLionel Sambuc */
143*11be35a1SLionel Sambuc
144*11be35a1SLionel Sambuc #ifdef TEST_LONG_DOUBLE
145*11be35a1SLionel Sambuc
146*11be35a1SLionel Sambuc ATF_TC(fpclassify_long_double);
ATF_TC_HEAD(fpclassify_long_double,tc)147*11be35a1SLionel Sambuc ATF_TC_HEAD(fpclassify_long_double, tc)
148*11be35a1SLionel Sambuc {
149*11be35a1SLionel Sambuc
150*11be35a1SLionel Sambuc atf_tc_set_md_var(tc, "descr", "Test long double operations");
151*11be35a1SLionel Sambuc }
152*11be35a1SLionel Sambuc
ATF_TC_BODY(fpclassify_long_double,tc)153*11be35a1SLionel Sambuc ATF_TC_BODY(fpclassify_long_double, tc)
154*11be35a1SLionel Sambuc {
155*11be35a1SLionel Sambuc long double d0, d1, d2, f, ip;
156*11be35a1SLionel Sambuc int e, i;
157*11be35a1SLionel Sambuc
158*11be35a1SLionel Sambuc d0 = LDBL_MIN;
159*11be35a1SLionel Sambuc ATF_REQUIRE_EQ(fpclassify(d0), FP_NORMAL);
160*11be35a1SLionel Sambuc f = frexpl(d0, &e);
161*11be35a1SLionel Sambuc ATF_REQUIRE_EQ(e, LDBL_MIN_EXP);
162*11be35a1SLionel Sambuc ATF_REQUIRE_EQ(f, 0.5);
163*11be35a1SLionel Sambuc d1 = d0;
164*11be35a1SLionel Sambuc
165*11be35a1SLionel Sambuc /* shift a "1" bit through the mantissa (skip the implicit bit) */
166*11be35a1SLionel Sambuc for (i = 1; i < LDBL_MANT_DIG; i++) {
167*11be35a1SLionel Sambuc d1 /= 2;
168*11be35a1SLionel Sambuc ATF_REQUIRE_EQ(fpclassify(d1), FP_SUBNORMAL);
169*11be35a1SLionel Sambuc ATF_REQUIRE(d1 > 0 && d1 < d0);
170*11be35a1SLionel Sambuc
171*11be35a1SLionel Sambuc d2 = ldexpl(d0, -i);
172*11be35a1SLionel Sambuc ATF_REQUIRE_EQ(d2, d1);
173*11be35a1SLionel Sambuc
174*11be35a1SLionel Sambuc d2 = modfl(d1, &ip);
175*11be35a1SLionel Sambuc ATF_REQUIRE_EQ(d2, d1);
176*11be35a1SLionel Sambuc ATF_REQUIRE_EQ(ip, 0);
177*11be35a1SLionel Sambuc
178*11be35a1SLionel Sambuc f = frexpl(d1, &e);
179*11be35a1SLionel Sambuc ATF_REQUIRE_EQ(e, LDBL_MIN_EXP - i);
180*11be35a1SLionel Sambuc ATF_REQUIRE_EQ(f, 0.5);
181*11be35a1SLionel Sambuc }
182*11be35a1SLionel Sambuc
183*11be35a1SLionel Sambuc d1 /= 2;
184*11be35a1SLionel Sambuc ATF_REQUIRE_EQ(fpclassify(d1), FP_ZERO);
185*11be35a1SLionel Sambuc f = frexpl(d1, &e);
186*11be35a1SLionel Sambuc ATF_REQUIRE_EQ(e, 0);
187*11be35a1SLionel Sambuc ATF_REQUIRE_EQ(f, 0);
188*11be35a1SLionel Sambuc }
189*11be35a1SLionel Sambuc #endif /* TEST_LONG_DOUBLE */
190*11be35a1SLionel Sambuc #endif /* _FLOAT_IEEE754 */
191*11be35a1SLionel Sambuc
ATF_TP_ADD_TCS(tp)192*11be35a1SLionel Sambuc ATF_TP_ADD_TCS(tp)
193*11be35a1SLionel Sambuc {
194*11be35a1SLionel Sambuc
195*11be35a1SLionel Sambuc #ifndef _FLOAT_IEEE754
196*11be35a1SLionel Sambuc ATF_TP_ADD_TC(tp, no_test);
197*11be35a1SLionel Sambuc #else
198*11be35a1SLionel Sambuc ATF_TP_ADD_TC(tp, fpclassify_float);
199*11be35a1SLionel Sambuc ATF_TP_ADD_TC(tp, fpclassify_double);
200*11be35a1SLionel Sambuc #ifdef TEST_LONG_DOUBLE
201*11be35a1SLionel Sambuc ATF_TP_ADD_TC(tp, fpclassify_long_double);
202*11be35a1SLionel Sambuc #endif /* TEST_LONG_DOUBLE */
203*11be35a1SLionel Sambuc #endif /* _FLOAT_IEEE754 */
204*11be35a1SLionel Sambuc
205*11be35a1SLionel Sambuc return atf_no_error();
206*11be35a1SLionel Sambuc }
207