1*c36e572eSmbuhl /* $OpenBSD: fmaxmin_test.c,v 1.1 2021/10/22 18:00:22 mbuhl Exp $ */ 2*c36e572eSmbuhl /*- 3*c36e572eSmbuhl * Copyright (c) 2008 David Schultz <das@FreeBSD.org> 4*c36e572eSmbuhl * All rights reserved. 5*c36e572eSmbuhl * 6*c36e572eSmbuhl * Redistribution and use in source and binary forms, with or without 7*c36e572eSmbuhl * modification, are permitted provided that the following conditions 8*c36e572eSmbuhl * are met: 9*c36e572eSmbuhl * 1. Redistributions of source code must retain the above copyright 10*c36e572eSmbuhl * notice, this list of conditions and the following disclaimer. 11*c36e572eSmbuhl * 2. Redistributions in binary form must reproduce the above copyright 12*c36e572eSmbuhl * notice, this list of conditions and the following disclaimer in the 13*c36e572eSmbuhl * documentation and/or other materials provided with the distribution. 14*c36e572eSmbuhl * 15*c36e572eSmbuhl * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16*c36e572eSmbuhl * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17*c36e572eSmbuhl * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18*c36e572eSmbuhl * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19*c36e572eSmbuhl * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20*c36e572eSmbuhl * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21*c36e572eSmbuhl * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22*c36e572eSmbuhl * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23*c36e572eSmbuhl * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24*c36e572eSmbuhl * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25*c36e572eSmbuhl * SUCH DAMAGE. 26*c36e572eSmbuhl */ 27*c36e572eSmbuhl 28*c36e572eSmbuhl #include "macros.h" 29*c36e572eSmbuhl 30*c36e572eSmbuhl /* 31*c36e572eSmbuhl * Tests for fmax{,f,l}() and fmin{,f,l}. 32*c36e572eSmbuhl */ 33*c36e572eSmbuhl 34*c36e572eSmbuhl #include <sys/cdefs.h> 35*c36e572eSmbuhl __FBSDID("$FreeBSD$"); 36*c36e572eSmbuhl 37*c36e572eSmbuhl #include <fenv.h> 38*c36e572eSmbuhl #include <float.h> 39*c36e572eSmbuhl #include <math.h> 40*c36e572eSmbuhl #include <stdio.h> 41*c36e572eSmbuhl 42*c36e572eSmbuhl #include "test-utils.h" 43*c36e572eSmbuhl 44*c36e572eSmbuhl #pragma STDC FENV_ACCESS ON 45*c36e572eSmbuhl 46*c36e572eSmbuhl /* 47*c36e572eSmbuhl * Test whether func(x, y) has the expected result, and make sure no 48*c36e572eSmbuhl * exceptions are raised. 49*c36e572eSmbuhl */ 50*c36e572eSmbuhl #define TEST(func, type, x, y, expected, rmode) do { \ 51*c36e572eSmbuhl type __x = (x); /* convert before we clear exceptions */ \ 52*c36e572eSmbuhl type __y = (y); \ 53*c36e572eSmbuhl ATF_REQUIRE_EQ(0, feclearexcept(ALL_STD_EXCEPT)); \ 54*c36e572eSmbuhl long double __result = func((__x), (__y)); \ 55*c36e572eSmbuhl CHECK_FP_EXCEPTIONS_MSG(0, ALL_STD_EXCEPT, \ 56*c36e572eSmbuhl #func "(%.20Lg, %.20Lg) rmode%d", (x), (y), rmode); \ 57*c36e572eSmbuhl ATF_CHECK_MSG(fpequal_cs(__result, (expected), true), \ 58*c36e572eSmbuhl #func "(%.20Lg, %.20Lg) rmode%d = %.20Lg, expected %.20Lg\n", \ 59*c36e572eSmbuhl (x), (y), rmode, __result, (expected)); \ 60*c36e572eSmbuhl } while (0) 61*c36e572eSmbuhl 62*c36e572eSmbuhl static void 63*c36e572eSmbuhl testall_r(long double big, long double small, int rmode) 64*c36e572eSmbuhl { 65*c36e572eSmbuhl long double expected_max = isnan(big) ? small : big; 66*c36e572eSmbuhl long double expected_min = isnan(small) ? big : small; 67*c36e572eSmbuhl TEST(fmaxf, float, big, small, expected_max, rmode); 68*c36e572eSmbuhl TEST(fmaxf, float, small, big, expected_max, rmode); 69*c36e572eSmbuhl TEST(fmax, double, big, small, expected_max, rmode); 70*c36e572eSmbuhl TEST(fmax, double, small, big, expected_max, rmode); 71*c36e572eSmbuhl TEST(fmaxl, long double, big, small, expected_max, rmode); 72*c36e572eSmbuhl TEST(fmaxl, long double, small, big, expected_max, rmode); 73*c36e572eSmbuhl TEST(fminf, float, big, small, expected_min, rmode); 74*c36e572eSmbuhl TEST(fminf, float, small, big, expected_min, rmode); 75*c36e572eSmbuhl TEST(fmin, double, big, small, expected_min, rmode); 76*c36e572eSmbuhl TEST(fmin, double, small, big, expected_min, rmode); 77*c36e572eSmbuhl TEST(fminl, long double, big, small, expected_min, rmode); 78*c36e572eSmbuhl TEST(fminl, long double, small, big, expected_min, rmode); 79*c36e572eSmbuhl } 80*c36e572eSmbuhl 81*c36e572eSmbuhl /* 82*c36e572eSmbuhl * Test all the functions: fmaxf, fmax, fmaxl, fminf, fmin, and fminl, 83*c36e572eSmbuhl * in all rounding modes and with the arguments in different orders. 84*c36e572eSmbuhl * The input 'big' must be >= 'small'. 85*c36e572eSmbuhl */ 86*c36e572eSmbuhl static void 87*c36e572eSmbuhl testall(long double big, long double small) 88*c36e572eSmbuhl { 89*c36e572eSmbuhl static const int rmodes[] = { 90*c36e572eSmbuhl FE_TONEAREST, FE_UPWARD, FE_DOWNWARD, FE_TOWARDZERO 91*c36e572eSmbuhl }; 92*c36e572eSmbuhl int i; 93*c36e572eSmbuhl 94*c36e572eSmbuhl for (i = 0; i < 4; i++) { 95*c36e572eSmbuhl fesetround(rmodes[i]); 96*c36e572eSmbuhl testall_r(big, small, rmodes[i]); 97*c36e572eSmbuhl } 98*c36e572eSmbuhl } 99*c36e572eSmbuhl 100*c36e572eSmbuhl ATF_TC_WITHOUT_HEAD(test1); 101*c36e572eSmbuhl ATF_TC_BODY(test1, tc) 102*c36e572eSmbuhl { 103*c36e572eSmbuhl testall(1.0, 0.0); 104*c36e572eSmbuhl } 105*c36e572eSmbuhl 106*c36e572eSmbuhl ATF_TC_WITHOUT_HEAD(test2); 107*c36e572eSmbuhl ATF_TC_BODY(test2, tc) 108*c36e572eSmbuhl { 109*c36e572eSmbuhl testall(42.0, nextafterf(42.0, -INFINITY)); 110*c36e572eSmbuhl } 111*c36e572eSmbuhl ATF_TC_WITHOUT_HEAD(test3); 112*c36e572eSmbuhl ATF_TC_BODY(test3, tc) 113*c36e572eSmbuhl { 114*c36e572eSmbuhl testall(nextafterf(42.0, INFINITY), 42.0); 115*c36e572eSmbuhl } 116*c36e572eSmbuhl 117*c36e572eSmbuhl ATF_TC_WITHOUT_HEAD(test4); 118*c36e572eSmbuhl ATF_TC_BODY(test4, tc) 119*c36e572eSmbuhl { 120*c36e572eSmbuhl testall(-5.0, -5.0); 121*c36e572eSmbuhl } 122*c36e572eSmbuhl 123*c36e572eSmbuhl ATF_TC_WITHOUT_HEAD(test5); 124*c36e572eSmbuhl ATF_TC_BODY(test5, tc) 125*c36e572eSmbuhl { 126*c36e572eSmbuhl testall(-3.0, -4.0); 127*c36e572eSmbuhl } 128*c36e572eSmbuhl 129*c36e572eSmbuhl ATF_TC_WITHOUT_HEAD(test6); 130*c36e572eSmbuhl ATF_TC_BODY(test6, tc) 131*c36e572eSmbuhl { 132*c36e572eSmbuhl testall(1.0, NAN); 133*c36e572eSmbuhl } 134*c36e572eSmbuhl ATF_TC_WITHOUT_HEAD(test7); 135*c36e572eSmbuhl ATF_TC_BODY(test7, tc) 136*c36e572eSmbuhl { 137*c36e572eSmbuhl testall(INFINITY, NAN); 138*c36e572eSmbuhl } 139*c36e572eSmbuhl 140*c36e572eSmbuhl ATF_TC_WITHOUT_HEAD(test8); 141*c36e572eSmbuhl ATF_TC_BODY(test8, tc) 142*c36e572eSmbuhl { 143*c36e572eSmbuhl testall(INFINITY, 1.0); 144*c36e572eSmbuhl } 145*c36e572eSmbuhl 146*c36e572eSmbuhl ATF_TC_WITHOUT_HEAD(test9); 147*c36e572eSmbuhl ATF_TC_BODY(test9, tc) 148*c36e572eSmbuhl { 149*c36e572eSmbuhl testall(-3.0, -INFINITY); 150*c36e572eSmbuhl } 151*c36e572eSmbuhl 152*c36e572eSmbuhl ATF_TC_WITHOUT_HEAD(test10); 153*c36e572eSmbuhl ATF_TC_BODY(test10, tc) 154*c36e572eSmbuhl { 155*c36e572eSmbuhl testall(3.0, -INFINITY); 156*c36e572eSmbuhl } 157*c36e572eSmbuhl 158*c36e572eSmbuhl ATF_TC_WITHOUT_HEAD(test11); 159*c36e572eSmbuhl ATF_TC_BODY(test11, tc) 160*c36e572eSmbuhl { 161*c36e572eSmbuhl testall(NAN, NAN); 162*c36e572eSmbuhl } 163*c36e572eSmbuhl 164*c36e572eSmbuhl ATF_TC_WITHOUT_HEAD(test12); 165*c36e572eSmbuhl ATF_TC_BODY(test12, tc) 166*c36e572eSmbuhl { 167*c36e572eSmbuhl /* This test isn't strictly required to work by C99. */ 168*c36e572eSmbuhl testall(0.0, -0.0); 169*c36e572eSmbuhl } 170*c36e572eSmbuhl 171*c36e572eSmbuhl 172*c36e572eSmbuhl ATF_TP_ADD_TCS(tp) 173*c36e572eSmbuhl { 174*c36e572eSmbuhl ATF_TP_ADD_TC(tp, test1); 175*c36e572eSmbuhl ATF_TP_ADD_TC(tp, test2); 176*c36e572eSmbuhl ATF_TP_ADD_TC(tp, test3); 177*c36e572eSmbuhl ATF_TP_ADD_TC(tp, test4); 178*c36e572eSmbuhl ATF_TP_ADD_TC(tp, test5); 179*c36e572eSmbuhl ATF_TP_ADD_TC(tp, test6); 180*c36e572eSmbuhl ATF_TP_ADD_TC(tp, test7); 181*c36e572eSmbuhl ATF_TP_ADD_TC(tp, test8); 182*c36e572eSmbuhl ATF_TP_ADD_TC(tp, test9); 183*c36e572eSmbuhl ATF_TP_ADD_TC(tp, test10); 184*c36e572eSmbuhl ATF_TP_ADD_TC(tp, test11); 185*c36e572eSmbuhl ATF_TP_ADD_TC(tp, test12); 186*c36e572eSmbuhl 187*c36e572eSmbuhl return (atf_no_error()); 188*c36e572eSmbuhl } 189