Home | History | Annotate | Line # | Download | only in libm
      1  1.12  riastrad /* $NetBSD: t_cos.c,v 1.12 2024/06/09 16:53:12 riastradh Exp $ */
      2   1.1    jruoho 
      3   1.1    jruoho /*-
      4   1.1    jruoho  * Copyright (c) 2011 The NetBSD Foundation, Inc.
      5   1.1    jruoho  * All rights reserved.
      6   1.1    jruoho  *
      7   1.1    jruoho  * This code is derived from software contributed to The NetBSD Foundation
      8   1.1    jruoho  * by Jukka Ruohonen.
      9   1.1    jruoho  *
     10   1.1    jruoho  * Redistribution and use in source and binary forms, with or without
     11   1.1    jruoho  * modification, are permitted provided that the following conditions
     12   1.1    jruoho  * are met:
     13   1.1    jruoho  * 1. Redistributions of source code must retain the above copyright
     14   1.1    jruoho  *    notice, this list of conditions and the following disclaimer.
     15   1.1    jruoho  * 2. Redistributions in binary form must reproduce the above copyright
     16   1.1    jruoho  *    notice, this list of conditions and the following disclaimer in the
     17   1.1    jruoho  *    documentation and/or other materials provided with the distribution.
     18   1.1    jruoho  *
     19   1.1    jruoho  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     20   1.1    jruoho  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     21   1.1    jruoho  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     22   1.1    jruoho  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     23   1.1    jruoho  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     24   1.1    jruoho  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     25   1.1    jruoho  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     26   1.1    jruoho  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     27   1.1    jruoho  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     28   1.1    jruoho  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     29   1.1    jruoho  * POSSIBILITY OF SUCH DAMAGE.
     30   1.1    jruoho  */
     31   1.1    jruoho 
     32   1.5  riastrad #include <assert.h>
     33   1.1    jruoho #include <atf-c.h>
     34   1.5  riastrad #include <float.h>
     35   1.1    jruoho #include <math.h>
     36   1.1    jruoho 
     37   1.1    jruoho static const struct {
     38   1.1    jruoho 	int		angle;
     39   1.1    jruoho 	double		x;
     40   1.1    jruoho 	double		y;
     41   1.5  riastrad 	float		fy;
     42   1.1    jruoho } angles[] = {
     43   1.5  riastrad 	{ -180, -3.141592653589793, -1.0000000000000000, 999 },
     44   1.5  riastrad 	{ -135, -2.356194490192345, -0.7071067811865476, 999 },
     45   1.5  riastrad 	{  -90, -1.5707963267948966, 6.123233995736766e-17, -4.3711388e-08 },
     46   1.5  riastrad 	{  -90, -1.5707963267948968, -1.6081226496766366e-16, -4.3711388e-08 },
     47   1.5  riastrad 	{  -45, -0.785398163397448,  0.7071067811865478, 999 },
     48   1.5  riastrad 	{    0,  0.000000000000000,  1.0000000000000000, 999 },
     49   1.5  riastrad 	{   30,  0.523598775598299,  0.8660254037844386, 999 },
     50   1.5  riastrad 	{   45,  0.785398163397448,  0.7071067811865478, 999 },
     51   1.5  riastrad 	{   60,  1.0471975511965976,  0.5000000000000001, 999 },
     52   1.5  riastrad 	{   60,  1.0471975511965979,  0.4999999999999999, 999 },
     53   1.5  riastrad 	{   90,  1.570796326794897, -3.8285686989269494e-16, -4.3711388e-08 },
     54   1.5  riastrad 	{  120,  2.0943951023931953, -0.4999999999999998, 999 },
     55   1.5  riastrad 	{  120,  2.0943951023931957, -0.5000000000000002, 999 },
     56   1.5  riastrad 	{  135,  2.356194490192345, -0.7071067811865476, 999 },
     57   1.5  riastrad 	{  150,  2.617993877991494, -0.8660254037844386, 999 },
     58   1.5  riastrad 	{  180,  3.141592653589793, -1.0000000000000000, 999 },
     59   1.5  riastrad 	{  270,  4.712388980384690, -1.8369701987210297e-16, 1.1924881e-08 },
     60   1.5  riastrad 	{  360,  6.283185307179586,  1.0000000000000000, 999 },
     61   1.1    jruoho };
     62   1.1    jruoho 
     63   1.8      maya /*
     64   1.8      maya  * cosl(3)
     65   1.8      maya  */
     66   1.8      maya ATF_TC(cosl_angles);
     67   1.8      maya ATF_TC_HEAD(cosl_angles, tc)
     68   1.8      maya {
     69   1.8      maya 	atf_tc_set_md_var(tc, "descr", "Test some selected angles");
     70   1.8      maya }
     71   1.8      maya 
     72   1.8      maya ATF_TC_BODY(cosl_angles, tc)
     73   1.8      maya {
     74   1.8      maya 	/*
     75   1.8      maya 	 * XXX The given data is for double, so take that
     76   1.8      maya 	 * into account and expect less precise results..
     77   1.8      maya 	 */
     78   1.8      maya 	const long double eps = DBL_EPSILON;
     79   1.8      maya 	size_t i;
     80   1.8      maya 
     81   1.8      maya 	for (i = 0; i < __arraycount(angles); i++) {
     82   1.8      maya 		int deg = angles[i].angle;
     83   1.8      maya 		long double theta = angles[i].x;
     84   1.8      maya 		long double cos_theta = angles[i].y;
     85   1.8      maya 
     86   1.8      maya 		assert(cos_theta != 0);
     87   1.8      maya 		if (!(fabsl((cosl(theta) - cos_theta)/cos_theta) <= eps)) {
     88   1.8      maya 			atf_tc_fail_nonfatal("cos(%d deg = %.17Lg) = %.17Lg"
     89   1.8      maya 			    " != %.17Lg",
     90   1.8      maya 			    deg, theta, cosl(theta), cos_theta);
     91   1.8      maya 		}
     92   1.8      maya 	}
     93   1.8      maya }
     94   1.8      maya 
     95   1.8      maya ATF_TC(cosl_nan);
     96   1.8      maya ATF_TC_HEAD(cosl_nan, tc)
     97   1.8      maya {
     98   1.8      maya 	atf_tc_set_md_var(tc, "descr", "Test cosl(NaN) == NaN");
     99   1.8      maya }
    100   1.8      maya 
    101   1.8      maya ATF_TC_BODY(cosl_nan, tc)
    102   1.8      maya {
    103   1.8      maya 	const long double x = 0.0L / 0.0L;
    104   1.8      maya 
    105   1.8      maya 	ATF_CHECK(isnan(x) != 0);
    106   1.8      maya 	ATF_CHECK(isnan(cosl(x)) != 0);
    107   1.8      maya }
    108   1.8      maya 
    109   1.8      maya ATF_TC(cosl_inf_neg);
    110   1.8      maya ATF_TC_HEAD(cosl_inf_neg, tc)
    111   1.8      maya {
    112   1.8      maya 	atf_tc_set_md_var(tc, "descr", "Test cosl(-Inf) == NaN");
    113   1.8      maya }
    114   1.8      maya 
    115   1.8      maya ATF_TC_BODY(cosl_inf_neg, tc)
    116   1.8      maya {
    117  1.12  riastrad 	const volatile long double x = -1.0L / 0.0L;
    118  1.12  riastrad 	const long double y = cosl(x);
    119   1.8      maya 
    120  1.12  riastrad 	ATF_CHECK_MSG(isnan(y), "y=%La", y);
    121   1.8      maya }
    122   1.8      maya 
    123   1.8      maya ATF_TC(cosl_inf_pos);
    124   1.8      maya ATF_TC_HEAD(cosl_inf_pos, tc)
    125   1.8      maya {
    126   1.8      maya 	atf_tc_set_md_var(tc, "descr", "Test cosl(+Inf) == NaN");
    127   1.8      maya }
    128   1.8      maya 
    129   1.8      maya ATF_TC_BODY(cosl_inf_pos, tc)
    130   1.8      maya {
    131  1.12  riastrad 	const volatile long double x = 1.0L / 0.0L;
    132  1.12  riastrad 	const long double y = cosl(x);
    133   1.8      maya 
    134  1.12  riastrad 	ATF_CHECK_MSG(isnan(y), "y=%La", y);
    135   1.8      maya }
    136   1.8      maya 
    137   1.8      maya ATF_TC(cosl_zero_neg);
    138   1.8      maya ATF_TC_HEAD(cosl_zero_neg, tc)
    139   1.8      maya {
    140   1.8      maya 	atf_tc_set_md_var(tc, "descr", "Test cosl(-0.0) == 1.0");
    141   1.8      maya }
    142   1.8      maya 
    143   1.8      maya ATF_TC_BODY(cosl_zero_neg, tc)
    144   1.8      maya {
    145   1.8      maya 	const long double x = -0.0L;
    146   1.8      maya 
    147   1.8      maya 	ATF_CHECK(cosl(x) == 1.0);
    148   1.8      maya }
    149   1.8      maya 
    150   1.8      maya ATF_TC(cosl_zero_pos);
    151   1.8      maya ATF_TC_HEAD(cosl_zero_pos, tc)
    152   1.8      maya {
    153   1.8      maya 	atf_tc_set_md_var(tc, "descr", "Test cosl(+0.0) == 1.0");
    154   1.8      maya }
    155   1.8      maya 
    156   1.8      maya ATF_TC_BODY(cosl_zero_pos, tc)
    157   1.8      maya {
    158   1.8      maya 	const long double x = 0.0L;
    159   1.8      maya 
    160   1.8      maya 	ATF_CHECK(cosl(x) == 1.0);
    161   1.8      maya }
    162   1.8      maya 
    163   1.1    jruoho /*
    164   1.1    jruoho  * cos(3)
    165   1.1    jruoho  */
    166   1.1    jruoho ATF_TC(cos_angles);
    167   1.1    jruoho ATF_TC_HEAD(cos_angles, tc)
    168   1.1    jruoho {
    169   1.1    jruoho 	atf_tc_set_md_var(tc, "descr", "Test some selected angles");
    170   1.1    jruoho }
    171   1.1    jruoho 
    172   1.1    jruoho ATF_TC_BODY(cos_angles, tc)
    173   1.1    jruoho {
    174   1.5  riastrad 	const double eps = DBL_EPSILON;
    175   1.1    jruoho 	size_t i;
    176   1.1    jruoho 
    177   1.1    jruoho 	for (i = 0; i < __arraycount(angles); i++) {
    178   1.5  riastrad 		int deg = angles[i].angle;
    179   1.5  riastrad 		double theta = angles[i].x;
    180   1.5  riastrad 		double cos_theta = angles[i].y;
    181   1.5  riastrad 
    182   1.5  riastrad 		assert(cos_theta != 0);
    183   1.5  riastrad 		if (!(fabs((cos(theta) - cos_theta)/cos_theta) <= eps)) {
    184   1.5  riastrad 			atf_tc_fail_nonfatal("cos(%d deg = %.17g) = %.17g"
    185   1.5  riastrad 			    " != %.17g",
    186   1.5  riastrad 			    deg, theta, cos(theta), cos_theta);
    187   1.5  riastrad 		}
    188   1.1    jruoho 	}
    189   1.1    jruoho }
    190   1.1    jruoho 
    191   1.1    jruoho ATF_TC(cos_nan);
    192   1.1    jruoho ATF_TC_HEAD(cos_nan, tc)
    193   1.1    jruoho {
    194   1.1    jruoho 	atf_tc_set_md_var(tc, "descr", "Test cos(NaN) == NaN");
    195   1.1    jruoho }
    196   1.1    jruoho 
    197   1.1    jruoho ATF_TC_BODY(cos_nan, tc)
    198   1.1    jruoho {
    199   1.1    jruoho 	const double x = 0.0L / 0.0L;
    200   1.1    jruoho 
    201   1.1    jruoho 	ATF_CHECK(isnan(x) != 0);
    202   1.1    jruoho 	ATF_CHECK(isnan(cos(x)) != 0);
    203   1.1    jruoho }
    204   1.1    jruoho 
    205   1.1    jruoho ATF_TC(cos_inf_neg);
    206   1.1    jruoho ATF_TC_HEAD(cos_inf_neg, tc)
    207   1.1    jruoho {
    208   1.1    jruoho 	atf_tc_set_md_var(tc, "descr", "Test cos(-Inf) == NaN");
    209   1.1    jruoho }
    210   1.1    jruoho 
    211   1.1    jruoho ATF_TC_BODY(cos_inf_neg, tc)
    212   1.1    jruoho {
    213  1.12  riastrad 	const volatile double x = -1.0 / 0.0;
    214  1.12  riastrad 	const double y = cos(x);
    215   1.1    jruoho 
    216  1.12  riastrad 	ATF_CHECK_MSG(isnan(y), "y=%a", y);
    217   1.1    jruoho }
    218   1.1    jruoho 
    219   1.1    jruoho ATF_TC(cos_inf_pos);
    220   1.1    jruoho ATF_TC_HEAD(cos_inf_pos, tc)
    221   1.1    jruoho {
    222   1.1    jruoho 	atf_tc_set_md_var(tc, "descr", "Test cos(+Inf) == NaN");
    223   1.1    jruoho }
    224   1.1    jruoho 
    225   1.1    jruoho ATF_TC_BODY(cos_inf_pos, tc)
    226   1.1    jruoho {
    227  1.12  riastrad 	const volatile double x = 1.0 / 0.0;
    228  1.12  riastrad 	const double y = cos(x);
    229   1.1    jruoho 
    230  1.12  riastrad 	ATF_CHECK_MSG(isnan(y), "y=%a", y);
    231   1.1    jruoho }
    232   1.1    jruoho 
    233   1.1    jruoho ATF_TC(cos_zero_neg);
    234   1.1    jruoho ATF_TC_HEAD(cos_zero_neg, tc)
    235   1.1    jruoho {
    236   1.1    jruoho 	atf_tc_set_md_var(tc, "descr", "Test cos(-0.0) == 1.0");
    237   1.1    jruoho }
    238   1.1    jruoho 
    239   1.1    jruoho ATF_TC_BODY(cos_zero_neg, tc)
    240   1.1    jruoho {
    241   1.1    jruoho 	const double x = -0.0L;
    242   1.1    jruoho 
    243   1.1    jruoho 	ATF_CHECK(cos(x) == 1.0);
    244   1.1    jruoho }
    245   1.1    jruoho 
    246   1.1    jruoho ATF_TC(cos_zero_pos);
    247   1.1    jruoho ATF_TC_HEAD(cos_zero_pos, tc)
    248   1.1    jruoho {
    249   1.1    jruoho 	atf_tc_set_md_var(tc, "descr", "Test cos(+0.0) == 1.0");
    250   1.1    jruoho }
    251   1.1    jruoho 
    252   1.1    jruoho ATF_TC_BODY(cos_zero_pos, tc)
    253   1.1    jruoho {
    254   1.1    jruoho 	const double x = 0.0L;
    255   1.1    jruoho 
    256   1.1    jruoho 	ATF_CHECK(cos(x) == 1.0);
    257   1.1    jruoho }
    258   1.1    jruoho 
    259   1.1    jruoho /*
    260   1.1    jruoho  * cosf(3)
    261   1.1    jruoho  */
    262   1.1    jruoho ATF_TC(cosf_angles);
    263   1.1    jruoho ATF_TC_HEAD(cosf_angles, tc)
    264   1.1    jruoho {
    265   1.1    jruoho 	atf_tc_set_md_var(tc, "descr", "Test some selected angles");
    266   1.1    jruoho }
    267   1.1    jruoho 
    268   1.1    jruoho ATF_TC_BODY(cosf_angles, tc)
    269   1.1    jruoho {
    270   1.5  riastrad 	const float eps = FLT_EPSILON;
    271   1.1    jruoho 	size_t i;
    272   1.1    jruoho 
    273   1.1    jruoho 	for (i = 0; i < __arraycount(angles); i++) {
    274   1.5  riastrad 		int deg = angles[i].angle;
    275   1.5  riastrad 		float theta = angles[i].x;
    276   1.5  riastrad 		float cos_theta = angles[i].fy;
    277   1.5  riastrad 
    278   1.9      maya 		/*
    279   1.9      maya 		 * Force rounding to float even if FLT_EVAL_METHOD=2,
    280   1.9      maya 		 * as is the case on i386.
    281   1.9      maya 		 *
    282   1.9      maya 		 * The volatile should not be necessary, by C99 Sec.
    283   1.9      maya 		 * 5.2.4.2.2. para. 8 on p. 24 which specifies that
    284  1.11  riastrad 		 * assignment and cast remove all extra range and
    285  1.11  riastrad 		 * precision, but is needed when we compile with
    286  1.11  riastrad 		 * -std=gnu99 which doesn't implement this semantics.
    287  1.11  riastrad 		 */
    288   1.9      maya 		volatile float result = cosf(theta);
    289   1.9      maya 
    290   1.5  riastrad 		if (cos_theta == 999)
    291   1.5  riastrad 			cos_theta = angles[i].y;
    292   1.5  riastrad 
    293   1.5  riastrad 		assert(cos_theta != 0);
    294   1.9      maya 		if (!(fabsf((result - cos_theta)/cos_theta) <= eps)) {
    295   1.7  riastrad 			atf_tc_fail_nonfatal("cosf(%d deg = %.8g) = %.8g"
    296   1.9      maya 			    " != %.8g", deg, theta, result, cos_theta);
    297   1.5  riastrad 		}
    298   1.1    jruoho 	}
    299   1.1    jruoho }
    300   1.1    jruoho 
    301   1.1    jruoho ATF_TC(cosf_nan);
    302   1.1    jruoho ATF_TC_HEAD(cosf_nan, tc)
    303   1.1    jruoho {
    304   1.1    jruoho 	atf_tc_set_md_var(tc, "descr", "Test cosf(NaN) == NaN");
    305   1.1    jruoho }
    306   1.1    jruoho 
    307   1.1    jruoho ATF_TC_BODY(cosf_nan, tc)
    308   1.1    jruoho {
    309   1.1    jruoho 	const float x = 0.0L / 0.0L;
    310   1.1    jruoho 
    311   1.1    jruoho 	ATF_CHECK(isnan(x) != 0);
    312   1.1    jruoho 	ATF_CHECK(isnan(cosf(x)) != 0);
    313   1.1    jruoho }
    314   1.1    jruoho 
    315   1.1    jruoho ATF_TC(cosf_inf_neg);
    316   1.1    jruoho ATF_TC_HEAD(cosf_inf_neg, tc)
    317   1.1    jruoho {
    318   1.1    jruoho 	atf_tc_set_md_var(tc, "descr", "Test cosf(-Inf) == NaN");
    319   1.1    jruoho }
    320   1.1    jruoho 
    321   1.1    jruoho ATF_TC_BODY(cosf_inf_neg, tc)
    322   1.1    jruoho {
    323  1.12  riastrad 	const volatile float x = -1.0f / 0.0f;
    324  1.12  riastrad 	const float y = cosf(x);
    325   1.1    jruoho 
    326  1.12  riastrad 	ATF_CHECK_MSG(isnan(y), "y=%a", y);
    327   1.1    jruoho }
    328   1.1    jruoho 
    329   1.1    jruoho ATF_TC(cosf_inf_pos);
    330   1.1    jruoho ATF_TC_HEAD(cosf_inf_pos, tc)
    331   1.1    jruoho {
    332   1.1    jruoho 	atf_tc_set_md_var(tc, "descr", "Test cosf(+Inf) == NaN");
    333   1.1    jruoho }
    334   1.1    jruoho 
    335   1.1    jruoho ATF_TC_BODY(cosf_inf_pos, tc)
    336   1.1    jruoho {
    337  1.12  riastrad 	const volatile float x = 1.0f / 0.0f;
    338  1.12  riastrad 	const float y = cosf(x);
    339   1.1    jruoho 
    340  1.12  riastrad 	ATF_CHECK_MSG(isnan(y), "y=%a", y);
    341   1.1    jruoho }
    342   1.1    jruoho 
    343   1.1    jruoho 
    344   1.1    jruoho ATF_TC(cosf_zero_neg);
    345   1.1    jruoho ATF_TC_HEAD(cosf_zero_neg, tc)
    346   1.1    jruoho {
    347   1.1    jruoho 	atf_tc_set_md_var(tc, "descr", "Test cosf(-0.0) == 1.0");
    348   1.1    jruoho }
    349   1.1    jruoho 
    350   1.1    jruoho ATF_TC_BODY(cosf_zero_neg, tc)
    351   1.1    jruoho {
    352   1.1    jruoho 	const float x = -0.0L;
    353   1.1    jruoho 
    354   1.1    jruoho 	ATF_CHECK(cosf(x) == 1.0);
    355   1.1    jruoho }
    356   1.1    jruoho 
    357   1.1    jruoho ATF_TC(cosf_zero_pos);
    358   1.1    jruoho ATF_TC_HEAD(cosf_zero_pos, tc)
    359   1.1    jruoho {
    360   1.1    jruoho 	atf_tc_set_md_var(tc, "descr", "Test cosf(+0.0) == 1.0");
    361   1.1    jruoho }
    362   1.1    jruoho 
    363   1.1    jruoho ATF_TC_BODY(cosf_zero_pos, tc)
    364   1.1    jruoho {
    365   1.1    jruoho 	const float x = 0.0L;
    366   1.1    jruoho 
    367   1.1    jruoho 	ATF_CHECK(cosf(x) == 1.0);
    368   1.1    jruoho }
    369   1.1    jruoho 
    370   1.1    jruoho ATF_TP_ADD_TCS(tp)
    371   1.1    jruoho {
    372  1.10  riastrad 
    373   1.8      maya 	ATF_TP_ADD_TC(tp, cosl_angles);
    374   1.8      maya 	ATF_TP_ADD_TC(tp, cosl_nan);
    375   1.8      maya 	ATF_TP_ADD_TC(tp, cosl_inf_neg);
    376   1.8      maya 	ATF_TP_ADD_TC(tp, cosl_inf_pos);
    377   1.8      maya 	ATF_TP_ADD_TC(tp, cosl_zero_neg);
    378   1.8      maya 	ATF_TP_ADD_TC(tp, cosl_zero_pos);
    379   1.1    jruoho 
    380   1.1    jruoho 	ATF_TP_ADD_TC(tp, cos_angles);
    381   1.1    jruoho 	ATF_TP_ADD_TC(tp, cos_nan);
    382   1.1    jruoho 	ATF_TP_ADD_TC(tp, cos_inf_neg);
    383   1.1    jruoho 	ATF_TP_ADD_TC(tp, cos_inf_pos);
    384   1.1    jruoho 	ATF_TP_ADD_TC(tp, cos_zero_neg);
    385   1.1    jruoho 	ATF_TP_ADD_TC(tp, cos_zero_pos);
    386   1.1    jruoho 
    387   1.1    jruoho 	ATF_TP_ADD_TC(tp, cosf_angles);
    388   1.1    jruoho 	ATF_TP_ADD_TC(tp, cosf_nan);
    389   1.1    jruoho 	ATF_TP_ADD_TC(tp, cosf_inf_neg);
    390   1.1    jruoho 	ATF_TP_ADD_TC(tp, cosf_inf_pos);
    391   1.1    jruoho 	ATF_TP_ADD_TC(tp, cosf_zero_neg);
    392   1.1    jruoho 	ATF_TP_ADD_TC(tp, cosf_zero_pos);
    393   1.1    jruoho 
    394   1.1    jruoho 	return atf_no_error();
    395   1.1    jruoho }
    396