14dc607e7SEnji Cooper /*-
24dc607e7SEnji Cooper * Copyright (c) 2008 David Schultz <das@FreeBSD.org>
34dc607e7SEnji Cooper * All rights reserved.
44dc607e7SEnji Cooper *
54dc607e7SEnji Cooper * Redistribution and use in source and binary forms, with or without
64dc607e7SEnji Cooper * modification, are permitted provided that the following conditions
74dc607e7SEnji Cooper * are met:
84dc607e7SEnji Cooper * 1. Redistributions of source code must retain the above copyright
94dc607e7SEnji Cooper * notice, this list of conditions and the following disclaimer.
104dc607e7SEnji Cooper * 2. Redistributions in binary form must reproduce the above copyright
114dc607e7SEnji Cooper * notice, this list of conditions and the following disclaimer in the
124dc607e7SEnji Cooper * documentation and/or other materials provided with the distribution.
134dc607e7SEnji Cooper *
144dc607e7SEnji Cooper * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
154dc607e7SEnji Cooper * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
164dc607e7SEnji Cooper * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
174dc607e7SEnji Cooper * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
184dc607e7SEnji Cooper * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
194dc607e7SEnji Cooper * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
204dc607e7SEnji Cooper * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
214dc607e7SEnji Cooper * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
224dc607e7SEnji Cooper * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
234dc607e7SEnji Cooper * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
244dc607e7SEnji Cooper * SUCH DAMAGE.
254dc607e7SEnji Cooper */
264dc607e7SEnji Cooper
274dc607e7SEnji Cooper /*
284dc607e7SEnji Cooper * Tests for fmax{,f,l}() and fmin{,f,l}.
294dc607e7SEnji Cooper */
304dc607e7SEnji Cooper
314dc607e7SEnji Cooper #include <sys/cdefs.h>
324dc607e7SEnji Cooper #include <fenv.h>
334dc607e7SEnji Cooper #include <float.h>
344dc607e7SEnji Cooper #include <math.h>
354dc607e7SEnji Cooper #include <stdio.h>
364dc607e7SEnji Cooper
374dc607e7SEnji Cooper #include "test-utils.h"
384dc607e7SEnji Cooper
394dc607e7SEnji Cooper #pragma STDC FENV_ACCESS ON
404dc607e7SEnji Cooper
414dc607e7SEnji Cooper /*
424dc607e7SEnji Cooper * Test whether func(x, y) has the expected result, and make sure no
434dc607e7SEnji Cooper * exceptions are raised.
444dc607e7SEnji Cooper */
45133bc645SAlex Richardson #define TEST(func, type, x, y, expected, rmode) do { \
464dc607e7SEnji Cooper type __x = (x); /* convert before we clear exceptions */ \
474dc607e7SEnji Cooper type __y = (y); \
48133bc645SAlex Richardson ATF_REQUIRE_EQ(0, feclearexcept(ALL_STD_EXCEPT)); \
494dc607e7SEnji Cooper long double __result = func((__x), (__y)); \
50133bc645SAlex Richardson CHECK_FP_EXCEPTIONS_MSG(0, ALL_STD_EXCEPT, \
51133bc645SAlex Richardson #func "(%.20Lg, %.20Lg) rmode%d", (x), (y), rmode); \
52*b424e003SAlex Richardson ATF_CHECK_MSG(fpequal_cs(__result, (expected), true), \
53133bc645SAlex Richardson #func "(%.20Lg, %.20Lg) rmode%d = %.20Lg, expected %.20Lg\n", \
54133bc645SAlex Richardson (x), (y), rmode, __result, (expected)); \
554dc607e7SEnji Cooper } while (0)
564dc607e7SEnji Cooper
57133bc645SAlex Richardson static void
testall_r(long double big,long double small,int rmode)58133bc645SAlex Richardson testall_r(long double big, long double small, int rmode)
594dc607e7SEnji Cooper {
604dc607e7SEnji Cooper long double expected_max = isnan(big) ? small : big;
614dc607e7SEnji Cooper long double expected_min = isnan(small) ? big : small;
62133bc645SAlex Richardson TEST(fmaxf, float, big, small, expected_max, rmode);
63133bc645SAlex Richardson TEST(fmaxf, float, small, big, expected_max, rmode);
64133bc645SAlex Richardson TEST(fmax, double, big, small, expected_max, rmode);
65133bc645SAlex Richardson TEST(fmax, double, small, big, expected_max, rmode);
66133bc645SAlex Richardson TEST(fmaxl, long double, big, small, expected_max, rmode);
67133bc645SAlex Richardson TEST(fmaxl, long double, small, big, expected_max, rmode);
68133bc645SAlex Richardson TEST(fminf, float, big, small, expected_min, rmode);
69133bc645SAlex Richardson TEST(fminf, float, small, big, expected_min, rmode);
70133bc645SAlex Richardson TEST(fmin, double, big, small, expected_min, rmode);
71133bc645SAlex Richardson TEST(fmin, double, small, big, expected_min, rmode);
72133bc645SAlex Richardson TEST(fminl, long double, big, small, expected_min, rmode);
73133bc645SAlex Richardson TEST(fminl, long double, small, big, expected_min, rmode);
744dc607e7SEnji Cooper }
754dc607e7SEnji Cooper
764dc607e7SEnji Cooper /*
774dc607e7SEnji Cooper * Test all the functions: fmaxf, fmax, fmaxl, fminf, fmin, and fminl,
784dc607e7SEnji Cooper * in all rounding modes and with the arguments in different orders.
794dc607e7SEnji Cooper * The input 'big' must be >= 'small'.
804dc607e7SEnji Cooper */
81abe427afSEnji Cooper static void
testall(long double big,long double small)82133bc645SAlex Richardson testall(long double big, long double small)
834dc607e7SEnji Cooper {
844dc607e7SEnji Cooper static const int rmodes[] = {
854dc607e7SEnji Cooper FE_TONEAREST, FE_UPWARD, FE_DOWNWARD, FE_TOWARDZERO
864dc607e7SEnji Cooper };
874dc607e7SEnji Cooper int i;
884dc607e7SEnji Cooper
894dc607e7SEnji Cooper for (i = 0; i < 4; i++) {
904dc607e7SEnji Cooper fesetround(rmodes[i]);
91133bc645SAlex Richardson testall_r(big, small, rmodes[i]);
924dc607e7SEnji Cooper }
934dc607e7SEnji Cooper }
944dc607e7SEnji Cooper
95133bc645SAlex Richardson ATF_TC_WITHOUT_HEAD(test1);
ATF_TC_BODY(test1,tc)96133bc645SAlex Richardson ATF_TC_BODY(test1, tc)
974dc607e7SEnji Cooper {
98133bc645SAlex Richardson testall(1.0, 0.0);
99133bc645SAlex Richardson }
1004dc607e7SEnji Cooper
101133bc645SAlex Richardson ATF_TC_WITHOUT_HEAD(test2);
ATF_TC_BODY(test2,tc)102133bc645SAlex Richardson ATF_TC_BODY(test2, tc)
103133bc645SAlex Richardson {
104133bc645SAlex Richardson testall(42.0, nextafterf(42.0, -INFINITY));
105133bc645SAlex Richardson }
106133bc645SAlex Richardson ATF_TC_WITHOUT_HEAD(test3);
ATF_TC_BODY(test3,tc)107133bc645SAlex Richardson ATF_TC_BODY(test3, tc)
108133bc645SAlex Richardson {
109133bc645SAlex Richardson testall(nextafterf(42.0, INFINITY), 42.0);
110133bc645SAlex Richardson }
1114dc607e7SEnji Cooper
112133bc645SAlex Richardson ATF_TC_WITHOUT_HEAD(test4);
ATF_TC_BODY(test4,tc)113133bc645SAlex Richardson ATF_TC_BODY(test4, tc)
114133bc645SAlex Richardson {
115133bc645SAlex Richardson testall(-5.0, -5.0);
116133bc645SAlex Richardson }
117133bc645SAlex Richardson
118133bc645SAlex Richardson ATF_TC_WITHOUT_HEAD(test5);
ATF_TC_BODY(test5,tc)119133bc645SAlex Richardson ATF_TC_BODY(test5, tc)
120133bc645SAlex Richardson {
121133bc645SAlex Richardson testall(-3.0, -4.0);
122133bc645SAlex Richardson }
123133bc645SAlex Richardson
124133bc645SAlex Richardson ATF_TC_WITHOUT_HEAD(test6);
ATF_TC_BODY(test6,tc)125133bc645SAlex Richardson ATF_TC_BODY(test6, tc)
126133bc645SAlex Richardson {
127133bc645SAlex Richardson testall(1.0, NAN);
128133bc645SAlex Richardson }
129133bc645SAlex Richardson ATF_TC_WITHOUT_HEAD(test7);
ATF_TC_BODY(test7,tc)130133bc645SAlex Richardson ATF_TC_BODY(test7, tc)
131133bc645SAlex Richardson {
132133bc645SAlex Richardson testall(INFINITY, NAN);
133133bc645SAlex Richardson }
1344dc607e7SEnji Cooper
135133bc645SAlex Richardson ATF_TC_WITHOUT_HEAD(test8);
ATF_TC_BODY(test8,tc)136133bc645SAlex Richardson ATF_TC_BODY(test8, tc)
137133bc645SAlex Richardson {
138133bc645SAlex Richardson testall(INFINITY, 1.0);
139133bc645SAlex Richardson }
140133bc645SAlex Richardson
141133bc645SAlex Richardson ATF_TC_WITHOUT_HEAD(test9);
ATF_TC_BODY(test9,tc)142133bc645SAlex Richardson ATF_TC_BODY(test9, tc)
143133bc645SAlex Richardson {
144133bc645SAlex Richardson testall(-3.0, -INFINITY);
145133bc645SAlex Richardson }
146133bc645SAlex Richardson
147133bc645SAlex Richardson ATF_TC_WITHOUT_HEAD(test10);
ATF_TC_BODY(test10,tc)148133bc645SAlex Richardson ATF_TC_BODY(test10, tc)
149133bc645SAlex Richardson {
150133bc645SAlex Richardson testall(3.0, -INFINITY);
151133bc645SAlex Richardson }
152133bc645SAlex Richardson
153133bc645SAlex Richardson ATF_TC_WITHOUT_HEAD(test11);
ATF_TC_BODY(test11,tc)154133bc645SAlex Richardson ATF_TC_BODY(test11, tc)
155133bc645SAlex Richardson {
156133bc645SAlex Richardson testall(NAN, NAN);
157133bc645SAlex Richardson }
158133bc645SAlex Richardson
159133bc645SAlex Richardson ATF_TC_WITHOUT_HEAD(test12);
ATF_TC_BODY(test12,tc)160133bc645SAlex Richardson ATF_TC_BODY(test12, tc)
161133bc645SAlex Richardson {
1624dc607e7SEnji Cooper /* This test isn't strictly required to work by C99. */
163133bc645SAlex Richardson testall(0.0, -0.0);
164133bc645SAlex Richardson }
1654dc607e7SEnji Cooper
166133bc645SAlex Richardson
ATF_TP_ADD_TCS(tp)167133bc645SAlex Richardson ATF_TP_ADD_TCS(tp)
168133bc645SAlex Richardson {
169133bc645SAlex Richardson ATF_TP_ADD_TC(tp, test1);
170133bc645SAlex Richardson ATF_TP_ADD_TC(tp, test2);
171133bc645SAlex Richardson ATF_TP_ADD_TC(tp, test3);
172133bc645SAlex Richardson ATF_TP_ADD_TC(tp, test4);
173133bc645SAlex Richardson ATF_TP_ADD_TC(tp, test5);
174133bc645SAlex Richardson ATF_TP_ADD_TC(tp, test6);
175133bc645SAlex Richardson ATF_TP_ADD_TC(tp, test7);
176133bc645SAlex Richardson ATF_TP_ADD_TC(tp, test8);
177133bc645SAlex Richardson ATF_TP_ADD_TC(tp, test9);
178133bc645SAlex Richardson ATF_TP_ADD_TC(tp, test10);
179133bc645SAlex Richardson ATF_TP_ADD_TC(tp, test11);
180133bc645SAlex Richardson ATF_TP_ADD_TC(tp, test12);
181133bc645SAlex Richardson
182133bc645SAlex Richardson return (atf_no_error());
1834dc607e7SEnji Cooper }
184