xref: /netbsd-src/tests/lib/libm/t_sincos.c (revision 49e81414d02e4ec5e7ea50e8f17dc05f6fc17a29)
1*49e81414Sriastradh /* $NetBSD: t_sincos.c,v 1.2 2024/05/06 15:53:46 riastradh Exp $ */
25dd94c5eSchristos 
35dd94c5eSchristos /*-
45dd94c5eSchristos  * Copyright (c) 2011, 2022 The NetBSD Foundation, Inc.
55dd94c5eSchristos  * All rights reserved.
65dd94c5eSchristos  *
75dd94c5eSchristos  * This code is derived from software contributed to The NetBSD Foundation
85dd94c5eSchristos  * by Jukka Ruohonen and Christos Zoulas
95dd94c5eSchristos  *
105dd94c5eSchristos  * Redistribution and use in source and binary forms, with or without
115dd94c5eSchristos  * modification, are permitted provided that the following conditions
125dd94c5eSchristos  * are met:
135dd94c5eSchristos  * 1. Redistributions of source code must retain the above copyright
145dd94c5eSchristos  *    notice, this list of conditions and the following disclaimer.
155dd94c5eSchristos  * 2. Redistributions in binary form must reproduce the above copyright
165dd94c5eSchristos  *    notice, this list of conditions and the following disclaimer in the
175dd94c5eSchristos  *    documentation and/or other materials provided with the distribution.
185dd94c5eSchristos  *
195dd94c5eSchristos  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
205dd94c5eSchristos  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
215dd94c5eSchristos  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
225dd94c5eSchristos  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
235dd94c5eSchristos  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
245dd94c5eSchristos  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
255dd94c5eSchristos  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
265dd94c5eSchristos  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
275dd94c5eSchristos  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
285dd94c5eSchristos  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
295dd94c5eSchristos  * POSSIBILITY OF SUCH DAMAGE.
305dd94c5eSchristos  */
315dd94c5eSchristos 
325dd94c5eSchristos #include <assert.h>
335dd94c5eSchristos #include <atf-c.h>
345dd94c5eSchristos #include <float.h>
355dd94c5eSchristos #include <math.h>
365dd94c5eSchristos #include <stdio.h>
375dd94c5eSchristos 
385dd94c5eSchristos static const struct {
395dd94c5eSchristos 	int		angle;
405dd94c5eSchristos 	double		x;
415dd94c5eSchristos 	double		y;
425dd94c5eSchristos 	float		fy;
435dd94c5eSchristos } sin_angles[] = {
445dd94c5eSchristos //	{ -360, -6.283185307179586,  2.4492935982947064e-16, -1.7484555e-07 },
455dd94c5eSchristos 	{ -180, -3.141592653589793, -1.2246467991473532e-16, 8.7422777e-08 },
465dd94c5eSchristos 	{ -135, -2.356194490192345, -0.7071067811865476, 999 },
475dd94c5eSchristos //	{  -90, -1.570796326794897, -1.0000000000000000, 999 },
485dd94c5eSchristos 	{  -45, -0.785398163397448, -0.7071067811865472, 999 },
495dd94c5eSchristos 	{    0,  0.000000000000000,  0.0000000000000000, 999 },
505dd94c5eSchristos 	{   30,  0.5235987755982989, 0.5000000000000000, 999 },
515dd94c5eSchristos 	{   45,  0.785398163397448,  0.7071067811865472, 999 },
525dd94c5eSchristos //	{   60,  1.047197551196598,  0.8660254037844388, 999 },
535dd94c5eSchristos 	{   90,  1.570796326794897,  1.0000000000000000, 999 },
545dd94c5eSchristos //	{  120,  2.094395102393195,  0.8660254037844389, 999 },
555dd94c5eSchristos 	{  135,  2.356194490192345,  0.7071067811865476, 999 },
565dd94c5eSchristos 	{  150,  2.617993877991494,  0.5000000000000003, 999 },
575dd94c5eSchristos 	{  180,  3.141592653589793,  1.2246467991473532e-16, -8.7422777e-08 },
585dd94c5eSchristos 	{  270,  4.712388980384690, -1.0000000000000000, 999 },
595dd94c5eSchristos 	{  360,  6.283185307179586, -2.4492935982947064e-16, 1.7484555e-07 },
605dd94c5eSchristos };
615dd94c5eSchristos 
625dd94c5eSchristos static const struct {
635dd94c5eSchristos 	int		angle;
645dd94c5eSchristos 	double		x;
655dd94c5eSchristos 	double		y;
665dd94c5eSchristos 	float		fy;
675dd94c5eSchristos } cos_angles[] = {
685dd94c5eSchristos 	{ -180, -3.141592653589793, -1.0000000000000000, 999 },
695dd94c5eSchristos 	{ -135, -2.356194490192345, -0.7071067811865476, 999 },
705dd94c5eSchristos //	{  -90, -1.5707963267948966, 6.123233995736766e-17, -4.3711388e-08 },
715dd94c5eSchristos //	{  -90, -1.5707963267948968, -1.6081226496766366e-16, -4.3711388e-08 },
725dd94c5eSchristos 	{  -45, -0.785398163397448,  0.7071067811865478, 999 },
735dd94c5eSchristos 	{    0,  0.000000000000000,  1.0000000000000000, 999 },
745dd94c5eSchristos 	{   30,  0.5235987755982989, 0.8660254037844386, 999 },
755dd94c5eSchristos 	{   45,  0.785398163397448,  0.7071067811865478, 999 },
765dd94c5eSchristos //	{   60,  1.0471975511965976,  0.5000000000000001, 999 },
775dd94c5eSchristos //	{   60,  1.0471975511965979,  0.4999999999999999, 999 },
785dd94c5eSchristos 	{   90,  1.570796326794897, -3.8285686989269494e-16, -4.3711388e-08 },
795dd94c5eSchristos //	{  120,  2.0943951023931953, -0.4999999999999998, 999 },
805dd94c5eSchristos //	{  120,  2.0943951023931957, -0.5000000000000002, 999 },
815dd94c5eSchristos 	{  135,  2.356194490192345, -0.7071067811865476, 999 },
825dd94c5eSchristos 	{  150,  2.617993877991494, -0.8660254037844386, 999 },
835dd94c5eSchristos 	{  180,  3.141592653589793, -1.0000000000000000, 999 },
845dd94c5eSchristos 	{  270,  4.712388980384690, -1.8369701987210297e-16, 1.1924881e-08 },
855dd94c5eSchristos 	{  360,  6.283185307179586,  1.0000000000000000, 999 },
865dd94c5eSchristos };
875dd94c5eSchristos 
885dd94c5eSchristos /*
895dd94c5eSchristos  * sincosl(3)
905dd94c5eSchristos  */
915dd94c5eSchristos ATF_TC(sincosl_angles);
ATF_TC_HEAD(sincosl_angles,tc)925dd94c5eSchristos ATF_TC_HEAD(sincosl_angles, tc)
935dd94c5eSchristos {
945dd94c5eSchristos 	atf_tc_set_md_var(tc, "descr", "Test some selected angles");
955dd94c5eSchristos }
965dd94c5eSchristos 
ATF_TC_BODY(sincosl_angles,tc)975dd94c5eSchristos ATF_TC_BODY(sincosl_angles, tc)
985dd94c5eSchristos {
995dd94c5eSchristos 	/*
1005dd94c5eSchristos 	 * XXX The given data is for double, so take that
1015dd94c5eSchristos 	 * into account and expect less precise results..
1025dd94c5eSchristos 	 */
1035dd94c5eSchristos 	const long double eps = DBL_EPSILON;
1045dd94c5eSchristos 	size_t i;
1055dd94c5eSchristos 
1065dd94c5eSchristos 	ATF_CHECK(__arraycount(sin_angles) == __arraycount(cos_angles));
1075dd94c5eSchristos 
1085dd94c5eSchristos 	for (i = 0; i < __arraycount(sin_angles); i++) {
1095dd94c5eSchristos 		ATF_CHECK_MSG(sin_angles[i].angle == cos_angles[i].angle,
1105dd94c5eSchristos 		    "%zu %d %d", i, sin_angles[i].angle, cos_angles[i].angle);
1115dd94c5eSchristos 		int deg = sin_angles[i].angle;
1125dd94c5eSchristos 		ATF_CHECK_MSG(sin_angles[i].x == cos_angles[i].x,
1135dd94c5eSchristos 		    "%zu %g %g", i, sin_angles[i].x, cos_angles[i].x);
1145dd94c5eSchristos 		long double theta = sin_angles[i].x;
1155dd94c5eSchristos 		long double sin_theta = sin_angles[i].y;
1165dd94c5eSchristos 		long double cos_theta = cos_angles[i].y;
1175dd94c5eSchristos 		long double s, c;
1185dd94c5eSchristos 
1195dd94c5eSchristos 		sincosl(theta, &s, &c);
1205dd94c5eSchristos 
1215dd94c5eSchristos 		if (fabsl((s - sin_theta)/sin_theta) > eps) {
1225dd94c5eSchristos 			atf_tc_fail_nonfatal("sin(%d deg = %.17Lg) = %.17Lg"
1235dd94c5eSchristos 			    " != %.17Lg",
1245dd94c5eSchristos 			    deg, theta, s, sin_theta);
1255dd94c5eSchristos 		}
1265dd94c5eSchristos 		if (fabsl((c - cos_theta)/cos_theta) > eps) {
1275dd94c5eSchristos 			atf_tc_fail_nonfatal("cos(%d deg = %.17Lg) = %.17Lg"
1285dd94c5eSchristos 			    " != %.17Lg",
1295dd94c5eSchristos 			    deg, theta, c, cos_theta);
1305dd94c5eSchristos 		}
1315dd94c5eSchristos 	}
1325dd94c5eSchristos }
1335dd94c5eSchristos 
1345dd94c5eSchristos ATF_TC(sincosl_nan);
ATF_TC_HEAD(sincosl_nan,tc)1355dd94c5eSchristos ATF_TC_HEAD(sincosl_nan, tc)
1365dd94c5eSchristos {
1375dd94c5eSchristos 	atf_tc_set_md_var(tc, "descr", "Test sincosl(NaN) == (NaN, NaN)");
1385dd94c5eSchristos }
1395dd94c5eSchristos 
ATF_TC_BODY(sincosl_nan,tc)1405dd94c5eSchristos ATF_TC_BODY(sincosl_nan, tc)
1415dd94c5eSchristos {
1425dd94c5eSchristos 	const long double x = 0.0L / 0.0L;
1435dd94c5eSchristos 	long double s, c;
1445dd94c5eSchristos 
1455dd94c5eSchristos 	sincosl(x, &s, &c);
1465dd94c5eSchristos 	ATF_CHECK(isnan(x) && isnan(s) && isnan(c));
1475dd94c5eSchristos }
1485dd94c5eSchristos 
1495dd94c5eSchristos ATF_TC(sincosl_inf_neg);
ATF_TC_HEAD(sincosl_inf_neg,tc)1505dd94c5eSchristos ATF_TC_HEAD(sincosl_inf_neg, tc)
1515dd94c5eSchristos {
1525dd94c5eSchristos 	atf_tc_set_md_var(tc, "descr", "Test sincosl(-Inf) == (NaN, NaN)");
1535dd94c5eSchristos }
1545dd94c5eSchristos 
ATF_TC_BODY(sincosl_inf_neg,tc)1555dd94c5eSchristos ATF_TC_BODY(sincosl_inf_neg, tc)
1565dd94c5eSchristos {
1575dd94c5eSchristos 	const long double x = -1.0L / 0.0L;
1585dd94c5eSchristos 	long double s, c;
1595dd94c5eSchristos 
1605dd94c5eSchristos 	sincosl(x, &s, &c);
1615dd94c5eSchristos 	ATF_CHECK(isnan(s) && isnan(c));
1625dd94c5eSchristos }
1635dd94c5eSchristos 
1645dd94c5eSchristos ATF_TC(sincosl_inf_pos);
ATF_TC_HEAD(sincosl_inf_pos,tc)1655dd94c5eSchristos ATF_TC_HEAD(sincosl_inf_pos, tc)
1665dd94c5eSchristos {
1675dd94c5eSchristos 	atf_tc_set_md_var(tc, "descr", "Test sincosl(+Inf) == (NaN, NaN)");
1685dd94c5eSchristos }
1695dd94c5eSchristos 
ATF_TC_BODY(sincosl_inf_pos,tc)1705dd94c5eSchristos ATF_TC_BODY(sincosl_inf_pos, tc)
1715dd94c5eSchristos {
1725dd94c5eSchristos 	const long double x = 1.0L / 0.0L;
1735dd94c5eSchristos 	long double s, c;
1745dd94c5eSchristos 
1755dd94c5eSchristos 	sincosl(x, &s, &c);
1765dd94c5eSchristos 	ATF_CHECK(isnan(s) && isnan(c));
1775dd94c5eSchristos }
1785dd94c5eSchristos 
1795dd94c5eSchristos 
1805dd94c5eSchristos ATF_TC(sincosl_zero_neg);
ATF_TC_HEAD(sincosl_zero_neg,tc)1815dd94c5eSchristos ATF_TC_HEAD(sincosl_zero_neg, tc)
1825dd94c5eSchristos {
1835dd94c5eSchristos 	atf_tc_set_md_var(tc, "descr", "Test sincosl(-0.0) == (0.0, 1.0)");
1845dd94c5eSchristos }
1855dd94c5eSchristos 
ATF_TC_BODY(sincosl_zero_neg,tc)1865dd94c5eSchristos ATF_TC_BODY(sincosl_zero_neg, tc)
1875dd94c5eSchristos {
1885dd94c5eSchristos 	const long double x = -0.0L;
1895dd94c5eSchristos 	long double s, c;
1905dd94c5eSchristos 
1915dd94c5eSchristos 	sincosl(x, &s, &c);
1925dd94c5eSchristos 	ATF_CHECK(s == 0.0 && c == 1.0);
1935dd94c5eSchristos }
1945dd94c5eSchristos 
1955dd94c5eSchristos ATF_TC(sincosl_zero_pos);
ATF_TC_HEAD(sincosl_zero_pos,tc)1965dd94c5eSchristos ATF_TC_HEAD(sincosl_zero_pos, tc)
1975dd94c5eSchristos {
1985dd94c5eSchristos 	atf_tc_set_md_var(tc, "descr", "Test sincosl(+0.0) == (0.0, 1.0)");
1995dd94c5eSchristos }
2005dd94c5eSchristos 
ATF_TC_BODY(sincosl_zero_pos,tc)2015dd94c5eSchristos ATF_TC_BODY(sincosl_zero_pos, tc)
2025dd94c5eSchristos {
2035dd94c5eSchristos 	const long double x = 0.0L;
2045dd94c5eSchristos 	long double s, c;
2055dd94c5eSchristos 
2065dd94c5eSchristos 	sincosl(x, &s, &c);
2075dd94c5eSchristos 	ATF_CHECK(s == 0.0 && c == 1.0);
2085dd94c5eSchristos }
2095dd94c5eSchristos 
2105dd94c5eSchristos /*
2115dd94c5eSchristos  * sincos(3)
2125dd94c5eSchristos  */
2135dd94c5eSchristos ATF_TC(sincos_angles);
ATF_TC_HEAD(sincos_angles,tc)2145dd94c5eSchristos ATF_TC_HEAD(sincos_angles, tc)
2155dd94c5eSchristos {
2165dd94c5eSchristos 	atf_tc_set_md_var(tc, "descr", "Test some selected angles");
2175dd94c5eSchristos }
2185dd94c5eSchristos 
ATF_TC_BODY(sincos_angles,tc)2195dd94c5eSchristos ATF_TC_BODY(sincos_angles, tc)
2205dd94c5eSchristos {
2215dd94c5eSchristos 	const double eps = DBL_EPSILON;
2225dd94c5eSchristos 	size_t i;
2235dd94c5eSchristos 
2245dd94c5eSchristos 	for (i = 0; i < __arraycount(sin_angles); i++) {
2255dd94c5eSchristos 		ATF_CHECK_MSG(sin_angles[i].angle == cos_angles[i].angle,
2265dd94c5eSchristos 		    "%zu %d %d", i, sin_angles[i].angle, cos_angles[i].angle);
2275dd94c5eSchristos 		int deg = sin_angles[i].angle;
2285dd94c5eSchristos 		ATF_CHECK_MSG(sin_angles[i].x == cos_angles[i].x,
2295dd94c5eSchristos 		    "%zu %g %g", i, sin_angles[i].x, cos_angles[i].x);
2305dd94c5eSchristos 		double theta = sin_angles[i].x;
2315dd94c5eSchristos 		double sin_theta = sin_angles[i].y;
2325dd94c5eSchristos 		double cos_theta = cos_angles[i].y;
2335dd94c5eSchristos 		double s, c;
2345dd94c5eSchristos 
2355dd94c5eSchristos 		sincos(theta, &s, &c);
2365dd94c5eSchristos 
2375dd94c5eSchristos 		if (fabs((s - sin_theta)/sin_theta) > eps) {
2385dd94c5eSchristos 			atf_tc_fail_nonfatal("sin(%d deg = %.17g) = %.17g"
2395dd94c5eSchristos 			    " != %.17g",
2405dd94c5eSchristos 			    deg, theta, s, sin_theta);
2415dd94c5eSchristos 		}
2425dd94c5eSchristos 		if (fabs((c - cos_theta)/cos_theta) > eps) {
2435dd94c5eSchristos 			atf_tc_fail_nonfatal("cos(%d deg = %.17g) = %.17g"
2445dd94c5eSchristos 			    " != %.17g",
2455dd94c5eSchristos 			    deg, theta, c, cos_theta);
2465dd94c5eSchristos 		}
2475dd94c5eSchristos 	}
2485dd94c5eSchristos }
2495dd94c5eSchristos 
2505dd94c5eSchristos ATF_TC(sincos_nan);
ATF_TC_HEAD(sincos_nan,tc)2515dd94c5eSchristos ATF_TC_HEAD(sincos_nan, tc)
2525dd94c5eSchristos {
2535dd94c5eSchristos 	atf_tc_set_md_var(tc, "descr", "Test sincos(NaN) == (NaN, NaN)");
2545dd94c5eSchristos }
2555dd94c5eSchristos 
ATF_TC_BODY(sincos_nan,tc)2565dd94c5eSchristos ATF_TC_BODY(sincos_nan, tc)
2575dd94c5eSchristos {
2585dd94c5eSchristos 	const double x = 0.0L / 0.0L;
2595dd94c5eSchristos 	double s, c;
2605dd94c5eSchristos 
2615dd94c5eSchristos 	sincos(x, &s, &c);
2625dd94c5eSchristos 	ATF_CHECK(isnan(x) && isnan(s) && isnan(c));
2635dd94c5eSchristos }
2645dd94c5eSchristos 
2655dd94c5eSchristos ATF_TC(sincos_inf_neg);
ATF_TC_HEAD(sincos_inf_neg,tc)2665dd94c5eSchristos ATF_TC_HEAD(sincos_inf_neg, tc)
2675dd94c5eSchristos {
2685dd94c5eSchristos 	atf_tc_set_md_var(tc, "descr", "Test sincos(-Inf) == (NaN, NaN)");
2695dd94c5eSchristos }
2705dd94c5eSchristos 
ATF_TC_BODY(sincos_inf_neg,tc)2715dd94c5eSchristos ATF_TC_BODY(sincos_inf_neg, tc)
2725dd94c5eSchristos {
2735dd94c5eSchristos 	const double x = -1.0L / 0.0L;
2745dd94c5eSchristos 	double s, c;
2755dd94c5eSchristos 
2765dd94c5eSchristos 	sincos(x, &s, &c);
2775dd94c5eSchristos 	ATF_CHECK(isnan(s) && isnan(c));
2785dd94c5eSchristos }
2795dd94c5eSchristos 
2805dd94c5eSchristos ATF_TC(sincos_inf_pos);
ATF_TC_HEAD(sincos_inf_pos,tc)2815dd94c5eSchristos ATF_TC_HEAD(sincos_inf_pos, tc)
2825dd94c5eSchristos {
2835dd94c5eSchristos 	atf_tc_set_md_var(tc, "descr", "Test sincos(+Inf) == (NaN, NaN)");
2845dd94c5eSchristos }
2855dd94c5eSchristos 
ATF_TC_BODY(sincos_inf_pos,tc)2865dd94c5eSchristos ATF_TC_BODY(sincos_inf_pos, tc)
2875dd94c5eSchristos {
2885dd94c5eSchristos 	const double x = 1.0L / 0.0L;
2895dd94c5eSchristos 	double s, c;
2905dd94c5eSchristos 
2915dd94c5eSchristos 	sincos(x, &s, &c);
2925dd94c5eSchristos 	ATF_CHECK(isnan(s) && isnan(c));
2935dd94c5eSchristos }
2945dd94c5eSchristos 
2955dd94c5eSchristos 
2965dd94c5eSchristos ATF_TC(sincos_zero_neg);
ATF_TC_HEAD(sincos_zero_neg,tc)2975dd94c5eSchristos ATF_TC_HEAD(sincos_zero_neg, tc)
2985dd94c5eSchristos {
2995dd94c5eSchristos 	atf_tc_set_md_var(tc, "descr", "Test sincos(-0.0) == (0.0, 1.0)");
3005dd94c5eSchristos }
3015dd94c5eSchristos 
ATF_TC_BODY(sincos_zero_neg,tc)3025dd94c5eSchristos ATF_TC_BODY(sincos_zero_neg, tc)
3035dd94c5eSchristos {
3045dd94c5eSchristos 	const double x = -0.0L;
3055dd94c5eSchristos 	double s, c;
3065dd94c5eSchristos 
3075dd94c5eSchristos 	sincos(x, &s, &c);
3085dd94c5eSchristos 	ATF_CHECK(s == 0 && c == 1.0);
3095dd94c5eSchristos }
3105dd94c5eSchristos 
3115dd94c5eSchristos ATF_TC(sincos_zero_pos);
ATF_TC_HEAD(sincos_zero_pos,tc)3125dd94c5eSchristos ATF_TC_HEAD(sincos_zero_pos, tc)
3135dd94c5eSchristos {
3145dd94c5eSchristos 	atf_tc_set_md_var(tc, "descr", "Test cos(+0.0) == (0.0, 1.0)");
3155dd94c5eSchristos }
3165dd94c5eSchristos 
ATF_TC_BODY(sincos_zero_pos,tc)3175dd94c5eSchristos ATF_TC_BODY(sincos_zero_pos, tc)
3185dd94c5eSchristos {
3195dd94c5eSchristos 	const double x = 0.0L;
3205dd94c5eSchristos 	double s, c;
3215dd94c5eSchristos 
3225dd94c5eSchristos 	sincos(x, &s, &c);
3235dd94c5eSchristos 	ATF_CHECK(s == 0 && c == 1.0);
3245dd94c5eSchristos }
3255dd94c5eSchristos 
3265dd94c5eSchristos /*
3275dd94c5eSchristos  * sincosf(3)
3285dd94c5eSchristos  */
3295dd94c5eSchristos ATF_TC(sincosf_angles);
ATF_TC_HEAD(sincosf_angles,tc)3305dd94c5eSchristos ATF_TC_HEAD(sincosf_angles, tc)
3315dd94c5eSchristos {
3325dd94c5eSchristos 	atf_tc_set_md_var(tc, "descr", "Test some selected angles");
3335dd94c5eSchristos }
3345dd94c5eSchristos 
ATF_TC_BODY(sincosf_angles,tc)3355dd94c5eSchristos ATF_TC_BODY(sincosf_angles, tc)
3365dd94c5eSchristos {
3375dd94c5eSchristos 	const float eps = FLT_EPSILON;
3385dd94c5eSchristos 	size_t i;
3395dd94c5eSchristos 
3405dd94c5eSchristos 	for (i = 0; i < __arraycount(sin_angles); i++) {
3415dd94c5eSchristos 		ATF_CHECK_MSG(sin_angles[i].angle == cos_angles[i].angle,
3425dd94c5eSchristos 		    "%zu %d %d", i, sin_angles[i].angle, cos_angles[i].angle);
3435dd94c5eSchristos 		int deg = sin_angles[i].angle;
3445dd94c5eSchristos 		ATF_CHECK_MSG(sin_angles[i].x == cos_angles[i].x,
3455dd94c5eSchristos 		    "%zu %g %g", i, sin_angles[i].x, cos_angles[i].x);
3465dd94c5eSchristos 		float theta = sin_angles[i].x;
3475dd94c5eSchristos 		float sin_theta = sin_angles[i].fy;
3485dd94c5eSchristos 		float cos_theta = cos_angles[i].fy;
3495dd94c5eSchristos 		float s, c;
3505dd94c5eSchristos 
3515dd94c5eSchristos 		sincosf(theta, &s, &c);
3525dd94c5eSchristos 		if (cos_theta == 999)
3535dd94c5eSchristos 			cos_theta = cos_angles[i].y;
3545dd94c5eSchristos 		if (sin_theta == 999)
3555dd94c5eSchristos 			sin_theta = sin_angles[i].y;
3565dd94c5eSchristos 
3575dd94c5eSchristos 		if (fabs((s - sin_theta)/sin_theta) > eps) {
3585dd94c5eSchristos 			atf_tc_fail_nonfatal("sin(%d deg = %.8g) = %.8g"
3595dd94c5eSchristos 			    " != %.8g",
3605dd94c5eSchristos 			    deg, theta, s, sin_theta);
3615dd94c5eSchristos 		}
3625dd94c5eSchristos 		if (fabs((c - cos_theta)/cos_theta) > eps) {
3635dd94c5eSchristos 			atf_tc_fail_nonfatal("cos(%d deg = %.8g) = %.8g"
3645dd94c5eSchristos 			    " != %.8g",
3655dd94c5eSchristos 			    deg, theta, c, cos_theta);
3665dd94c5eSchristos 		}
3675dd94c5eSchristos 	}
3685dd94c5eSchristos }
3695dd94c5eSchristos 
3705dd94c5eSchristos ATF_TC(sincosf_nan);
ATF_TC_HEAD(sincosf_nan,tc)3715dd94c5eSchristos ATF_TC_HEAD(sincosf_nan, tc)
3725dd94c5eSchristos {
3735dd94c5eSchristos 	atf_tc_set_md_var(tc, "descr", "Test cosf(NaN) == (NaN, NaN)");
3745dd94c5eSchristos }
3755dd94c5eSchristos 
ATF_TC_BODY(sincosf_nan,tc)3765dd94c5eSchristos ATF_TC_BODY(sincosf_nan, tc)
3775dd94c5eSchristos {
3785dd94c5eSchristos 	const float x = 0.0L / 0.0L;
3795dd94c5eSchristos 	float s, c;
3805dd94c5eSchristos 
3815dd94c5eSchristos 	sincosf(x, &s, &c);
3825dd94c5eSchristos 	ATF_CHECK(isnan(x) && isnan(s) && isnan(c));
3835dd94c5eSchristos }
3845dd94c5eSchristos 
3855dd94c5eSchristos ATF_TC(sincosf_inf_neg);
ATF_TC_HEAD(sincosf_inf_neg,tc)3865dd94c5eSchristos ATF_TC_HEAD(sincosf_inf_neg, tc)
3875dd94c5eSchristos {
3885dd94c5eSchristos 	atf_tc_set_md_var(tc, "descr", "Test cosf(-Inf) == (NaN, NaN)");
3895dd94c5eSchristos }
3905dd94c5eSchristos 
ATF_TC_BODY(sincosf_inf_neg,tc)3915dd94c5eSchristos ATF_TC_BODY(sincosf_inf_neg, tc)
3925dd94c5eSchristos {
3935dd94c5eSchristos 	const float x = -1.0L / 0.0L;
3945dd94c5eSchristos 	float s, c;
3955dd94c5eSchristos 
3965dd94c5eSchristos 	sincosf(x, &s, &c);
3975dd94c5eSchristos 	ATF_CHECK(isnan(s) && isnan(c));
3985dd94c5eSchristos 
3995dd94c5eSchristos }
4005dd94c5eSchristos 
4015dd94c5eSchristos ATF_TC(sincosf_inf_pos);
ATF_TC_HEAD(sincosf_inf_pos,tc)4025dd94c5eSchristos ATF_TC_HEAD(sincosf_inf_pos, tc)
4035dd94c5eSchristos {
4045dd94c5eSchristos 	atf_tc_set_md_var(tc, "descr", "Test sincosf(+Inf) == (NaN, NaN)");
4055dd94c5eSchristos }
4065dd94c5eSchristos 
ATF_TC_BODY(sincosf_inf_pos,tc)4075dd94c5eSchristos ATF_TC_BODY(sincosf_inf_pos, tc)
4085dd94c5eSchristos {
4095dd94c5eSchristos 	const float x = 1.0L / 0.0L;
4105dd94c5eSchristos 	float s, c;
4115dd94c5eSchristos 
4125dd94c5eSchristos 	sincosf(x, &s, &c);
4135dd94c5eSchristos 	ATF_CHECK(isnan(s) && isnan(c));
4145dd94c5eSchristos }
4155dd94c5eSchristos 
4165dd94c5eSchristos 
4175dd94c5eSchristos ATF_TC(sincosf_zero_neg);
ATF_TC_HEAD(sincosf_zero_neg,tc)4185dd94c5eSchristos ATF_TC_HEAD(sincosf_zero_neg, tc)
4195dd94c5eSchristos {
4205dd94c5eSchristos 	atf_tc_set_md_var(tc, "descr", "Test sincosf(-0.0) == (0.0, 1.0)");
4215dd94c5eSchristos }
4225dd94c5eSchristos 
ATF_TC_BODY(sincosf_zero_neg,tc)4235dd94c5eSchristos ATF_TC_BODY(sincosf_zero_neg, tc)
4245dd94c5eSchristos {
4255dd94c5eSchristos 	const float x = -0.0L;
4265dd94c5eSchristos 	float s, c;
4275dd94c5eSchristos 
4285dd94c5eSchristos 	sincosf(x, &s, &c);
4295dd94c5eSchristos 
4305dd94c5eSchristos 	ATF_CHECK(s == 0.0 && c == 1.0);
4315dd94c5eSchristos }
4325dd94c5eSchristos 
4335dd94c5eSchristos ATF_TC(sincosf_zero_pos);
ATF_TC_HEAD(sincosf_zero_pos,tc)4345dd94c5eSchristos ATF_TC_HEAD(sincosf_zero_pos, tc)
4355dd94c5eSchristos {
4365dd94c5eSchristos 	atf_tc_set_md_var(tc, "descr", "Test sincosf(+0.0) == (0.0, 1.0)");
4375dd94c5eSchristos }
4385dd94c5eSchristos 
ATF_TC_BODY(sincosf_zero_pos,tc)4395dd94c5eSchristos ATF_TC_BODY(sincosf_zero_pos, tc)
4405dd94c5eSchristos {
4415dd94c5eSchristos 	const float x = 0.0L;
4425dd94c5eSchristos 
4435dd94c5eSchristos 	float s, c;
4445dd94c5eSchristos 
4455dd94c5eSchristos 	sincosf(x, &s, &c);
4465dd94c5eSchristos 
4475dd94c5eSchristos 	ATF_CHECK(s == 0 && c == 1.0);
4485dd94c5eSchristos }
4495dd94c5eSchristos 
ATF_TP_ADD_TCS(tp)4505dd94c5eSchristos ATF_TP_ADD_TCS(tp)
4515dd94c5eSchristos {
452*49e81414Sriastradh 
4535dd94c5eSchristos 	ATF_TP_ADD_TC(tp, sincosl_angles);
4545dd94c5eSchristos 	ATF_TP_ADD_TC(tp, sincosl_nan);
4555dd94c5eSchristos 	ATF_TP_ADD_TC(tp, sincosl_inf_neg);
4565dd94c5eSchristos 	ATF_TP_ADD_TC(tp, sincosl_inf_pos);
4575dd94c5eSchristos 	ATF_TP_ADD_TC(tp, sincosl_zero_neg);
4585dd94c5eSchristos 	ATF_TP_ADD_TC(tp, sincosl_zero_pos);
4595dd94c5eSchristos 
4605dd94c5eSchristos 	ATF_TP_ADD_TC(tp, sincos_angles);
4615dd94c5eSchristos 	ATF_TP_ADD_TC(tp, sincos_nan);
4625dd94c5eSchristos 	ATF_TP_ADD_TC(tp, sincos_inf_neg);
4635dd94c5eSchristos 	ATF_TP_ADD_TC(tp, sincos_inf_pos);
4645dd94c5eSchristos 	ATF_TP_ADD_TC(tp, sincos_zero_neg);
4655dd94c5eSchristos 	ATF_TP_ADD_TC(tp, sincos_zero_pos);
4665dd94c5eSchristos 
4675dd94c5eSchristos 	ATF_TP_ADD_TC(tp, sincosf_angles);
4685dd94c5eSchristos 	ATF_TP_ADD_TC(tp, sincosf_nan);
4695dd94c5eSchristos 	ATF_TP_ADD_TC(tp, sincosf_inf_neg);
4705dd94c5eSchristos 	ATF_TP_ADD_TC(tp, sincosf_inf_pos);
4715dd94c5eSchristos 	ATF_TP_ADD_TC(tp, sincosf_zero_neg);
4725dd94c5eSchristos 	ATF_TP_ADD_TC(tp, sincosf_zero_pos);
4735dd94c5eSchristos 
4745dd94c5eSchristos 	return atf_no_error();
4755dd94c5eSchristos }
476