From owner-svn-src-all@FreeBSD.ORG Fri Oct 21 06:36:40 2011 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id C0BE2106566C; Fri, 21 Oct 2011 06:36:40 +0000 (UTC) (envelope-from das@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id AF4A38FC1B; Fri, 21 Oct 2011 06:36:40 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id p9L6aeou010372; Fri, 21 Oct 2011 06:36:40 GMT (envelope-from das@svn.freebsd.org) Received: (from das@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id p9L6aeqq010370; Fri, 21 Oct 2011 06:36:40 GMT (envelope-from das@svn.freebsd.org) Message-Id: <201110210636.p9L6aeqq010370@svn.freebsd.org> From: David Schultz Date: Fri, 21 Oct 2011 06:36:40 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r226605 - head/tools/regression/lib/msun X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 21 Oct 2011 06:36:40 -0000 Author: das Date: Fri Oct 21 06:36:40 2011 New Revision: 226605 URL: http://svn.freebsd.org/changeset/base/226605 Log: Add regression tests for modf{,f,l}(). Modified: head/tools/regression/lib/msun/test-nearbyint.c Modified: head/tools/regression/lib/msun/test-nearbyint.c ============================================================================== --- head/tools/regression/lib/msun/test-nearbyint.c Fri Oct 21 06:35:58 2011 (r226604) +++ head/tools/regression/lib/msun/test-nearbyint.c Fri Oct 21 06:36:40 2011 (r226605) @@ -30,7 +30,6 @@ * TODO: * - adapt tests for rint(3) * - tests for harder values (more mantissa bits than float) - * - tests in other rounding modes */ #include @@ -44,6 +43,27 @@ __FBSDID("$FreeBSD$"); #define ALL_STD_EXCEPT (FE_DIVBYZERO | FE_INEXACT | FE_INVALID | \ FE_OVERFLOW | FE_UNDERFLOW) +static int testnum; + +static const int rmodes[] = { + FE_TONEAREST, FE_DOWNWARD, FE_UPWARD, FE_TOWARDZERO, +}; + +static const struct { + float in; + float out[3]; /* one answer per rounding mode except towardzero */ +} tests[] = { +/* input output (expected) */ + { 0.0, { 0.0, 0.0, 0.0 }}, + { 0.5, { 0.0, 0.0, 1.0 }}, + { M_PI, { 3.0, 3.0, 4.0 }}, + { 65536.5, { 65536, 65536, 65537 }}, + { INFINITY, { INFINITY, INFINITY, INFINITY }}, + { NAN, { NAN, NAN, NAN }}, +}; + +static const int ntests = sizeof(tests) / sizeof(tests[0]); + /* * Compare d1 and d2 using special rules: NaN == NaN and +0 != -0. * Fail an assertion if they differ. @@ -57,44 +77,106 @@ fpequal(long double d1, long double d2) return (copysignl(1.0, d1) == copysignl(1.0, d2)); } -static void testit(int testnum, float in, float out) +/* Get the appropriate result for the current rounding mode. */ +static float +get_output(int testindex, int rmodeindex, int negative) { + double out; - feclearexcept(ALL_STD_EXCEPT); - assert(fpequal(out, nearbyintf(in))); - assert(fpequal(-out, nearbyintf(-in))); - assert(fetestexcept(ALL_STD_EXCEPT) == 0); - - assert(fpequal(out, nearbyint(in))); - assert(fpequal(-out, nearbyint(-in))); - assert(fetestexcept(ALL_STD_EXCEPT) == 0); - - assert(fpequal(out, nearbyintl(in))); - assert(fpequal(-out, nearbyintl(-in))); - assert(fetestexcept(ALL_STD_EXCEPT) == 0); + if (negative) { /* swap downwards and upwards if input is negative */ + if (rmodeindex == 1) + rmodeindex = 2; + else if (rmodeindex == 2) + rmodeindex = 1; + } + if (rmodeindex == 3) /* FE_TOWARDZERO uses the value for downwards */ + rmodeindex = 1; + out = tests[testindex].out[rmodeindex]; + return (negative ? -out : out); +} - printf("ok %d\t\t# nearbyint(%g)\n", testnum, in); +static void +test_nearby(int testindex) +{ + float in, out; + int i; + + for (i = 0; i < sizeof(rmodes) / sizeof(rmodes[0]); i++) { + fesetround(rmodes[i]); + feclearexcept(ALL_STD_EXCEPT); + + in = tests[testindex].in; + out = get_output(testindex, i, 0); + assert(fpequal(out, nearbyintf(in))); + assert(fpequal(out, nearbyint(in))); + assert(fpequal(out, nearbyintl(in))); + assert(fetestexcept(ALL_STD_EXCEPT) == 0); + + in = -tests[testindex].in; + out = get_output(testindex, i, 1); + assert(fpequal(out, nearbyintf(in))); + assert(fpequal(out, nearbyint(in))); + assert(fpequal(out, nearbyintl(in))); + assert(fetestexcept(ALL_STD_EXCEPT) == 0); + } + + printf("ok %d\t\t# nearbyint(+%g)\n", testnum++, in); } -static const float tests[] = { -/* input output (expected) */ - 0.0, 0.0, - 0.5, 0.0, - M_PI, 3, - 65536.5, 65536, - INFINITY, INFINITY, - NAN, NAN, -}; +static void +test_modf(int testindex) +{ + float in, out; + float ipartf, ipart_expected; + double ipart; + long double ipartl; + int i; + + for (i = 0; i < sizeof(rmodes) / sizeof(rmodes[0]); i++) { + fesetround(rmodes[i]); + feclearexcept(ALL_STD_EXCEPT); + + in = tests[testindex].in; + ipart_expected = tests[testindex].out[1]; + out = copysignf( + isinf(ipart_expected) ? 0.0 : in - ipart_expected, in); + ipartl = ipart = ipartf = 42.0; + + assert(fpequal(out, modff(in, &ipartf))); + assert(fpequal(ipart_expected, ipartf)); + assert(fpequal(out, modf(in, &ipart))); + assert(fpequal(ipart_expected, ipart)); + assert(fpequal(out, modfl(in, &ipartl))); + assert(fpequal(ipart_expected, ipartl)); + assert(fetestexcept(ALL_STD_EXCEPT) == 0); + + in = -in; + ipart_expected = -ipart_expected; + out = -out; + ipartl = ipart = ipartf = 42.0; + assert(fpequal(out, modff(in, &ipartf))); + assert(fpequal(ipart_expected, ipartf)); + assert(fpequal(out, modf(in, &ipart))); + assert(fpequal(ipart_expected, ipart)); + assert(fpequal(out, modfl(in, &ipartl))); + assert(fpequal(ipart_expected, ipartl)); + assert(fetestexcept(ALL_STD_EXCEPT) == 0); + } + + printf("ok %d\t\t# modf(+%g)\n", testnum++, in); +} int main(int argc, char *argv[]) { - static const int ntests = sizeof(tests) / sizeof(tests[0]) / 2; int i; - printf("1..%d\n", ntests); - for (i = 0; i < ntests; i++) - testit(i + 1, tests[i * 2], tests[i * 2 + 1]); + printf("1..%d\n", ntests * 2); + testnum = 1; + for (i = 0; i < ntests; i++) { + test_nearby(i); + test_modf(i); + } return (0); }