Home | History | Annotate | Line # | Download | only in libm
t_cos.c revision 1.10
      1  1.10  riastrad /* $NetBSD: t_cos.c,v 1.10 2024/05/06 15:44:08 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.8      maya 	const long double x = -1.0L / 0.0L;
    118   1.8      maya 
    119   1.8      maya 	ATF_CHECK(isnan(cosl(x)) != 0);
    120   1.8      maya }
    121   1.8      maya 
    122   1.8      maya ATF_TC(cosl_inf_pos);
    123   1.8      maya ATF_TC_HEAD(cosl_inf_pos, tc)
    124   1.8      maya {
    125   1.8      maya 	atf_tc_set_md_var(tc, "descr", "Test cosl(+Inf) == NaN");
    126   1.8      maya }
    127   1.8      maya 
    128   1.8      maya ATF_TC_BODY(cosl_inf_pos, tc)
    129   1.8      maya {
    130   1.8      maya 	const long double x = 1.0L / 0.0L;
    131   1.8      maya 
    132   1.8      maya 	ATF_CHECK(isnan(cosl(x)) != 0);
    133   1.8      maya }
    134   1.8      maya 
    135   1.8      maya ATF_TC(cosl_zero_neg);
    136   1.8      maya ATF_TC_HEAD(cosl_zero_neg, tc)
    137   1.8      maya {
    138   1.8      maya 	atf_tc_set_md_var(tc, "descr", "Test cosl(-0.0) == 1.0");
    139   1.8      maya }
    140   1.8      maya 
    141   1.8      maya ATF_TC_BODY(cosl_zero_neg, tc)
    142   1.8      maya {
    143   1.8      maya 	const long double x = -0.0L;
    144   1.8      maya 
    145   1.8      maya 	ATF_CHECK(cosl(x) == 1.0);
    146   1.8      maya }
    147   1.8      maya 
    148   1.8      maya ATF_TC(cosl_zero_pos);
    149   1.8      maya ATF_TC_HEAD(cosl_zero_pos, tc)
    150   1.8      maya {
    151   1.8      maya 	atf_tc_set_md_var(tc, "descr", "Test cosl(+0.0) == 1.0");
    152   1.8      maya }
    153   1.8      maya 
    154   1.8      maya ATF_TC_BODY(cosl_zero_pos, tc)
    155   1.8      maya {
    156   1.8      maya 	const long double x = 0.0L;
    157   1.8      maya 
    158   1.8      maya 	ATF_CHECK(cosl(x) == 1.0);
    159   1.8      maya }
    160   1.8      maya 
    161   1.1    jruoho /*
    162   1.1    jruoho  * cos(3)
    163   1.1    jruoho  */
    164   1.1    jruoho ATF_TC(cos_angles);
    165   1.1    jruoho ATF_TC_HEAD(cos_angles, tc)
    166   1.1    jruoho {
    167   1.1    jruoho 	atf_tc_set_md_var(tc, "descr", "Test some selected angles");
    168   1.1    jruoho }
    169   1.1    jruoho 
    170   1.1    jruoho ATF_TC_BODY(cos_angles, tc)
    171   1.1    jruoho {
    172   1.5  riastrad 	const double eps = DBL_EPSILON;
    173   1.1    jruoho 	size_t i;
    174   1.1    jruoho 
    175   1.1    jruoho 	for (i = 0; i < __arraycount(angles); i++) {
    176   1.5  riastrad 		int deg = angles[i].angle;
    177   1.5  riastrad 		double theta = angles[i].x;
    178   1.5  riastrad 		double cos_theta = angles[i].y;
    179   1.5  riastrad 
    180   1.5  riastrad 		assert(cos_theta != 0);
    181   1.5  riastrad 		if (!(fabs((cos(theta) - cos_theta)/cos_theta) <= eps)) {
    182   1.5  riastrad 			atf_tc_fail_nonfatal("cos(%d deg = %.17g) = %.17g"
    183   1.5  riastrad 			    " != %.17g",
    184   1.5  riastrad 			    deg, theta, cos(theta), cos_theta);
    185   1.5  riastrad 		}
    186   1.1    jruoho 	}
    187   1.1    jruoho }
    188   1.1    jruoho 
    189   1.1    jruoho ATF_TC(cos_nan);
    190   1.1    jruoho ATF_TC_HEAD(cos_nan, tc)
    191   1.1    jruoho {
    192   1.1    jruoho 	atf_tc_set_md_var(tc, "descr", "Test cos(NaN) == NaN");
    193   1.1    jruoho }
    194   1.1    jruoho 
    195   1.1    jruoho ATF_TC_BODY(cos_nan, tc)
    196   1.1    jruoho {
    197   1.1    jruoho 	const double x = 0.0L / 0.0L;
    198   1.1    jruoho 
    199   1.1    jruoho 	ATF_CHECK(isnan(x) != 0);
    200   1.1    jruoho 	ATF_CHECK(isnan(cos(x)) != 0);
    201   1.1    jruoho }
    202   1.1    jruoho 
    203   1.1    jruoho ATF_TC(cos_inf_neg);
    204   1.1    jruoho ATF_TC_HEAD(cos_inf_neg, tc)
    205   1.1    jruoho {
    206   1.1    jruoho 	atf_tc_set_md_var(tc, "descr", "Test cos(-Inf) == NaN");
    207   1.1    jruoho }
    208   1.1    jruoho 
    209   1.1    jruoho ATF_TC_BODY(cos_inf_neg, tc)
    210   1.1    jruoho {
    211   1.1    jruoho 	const double x = -1.0L / 0.0L;
    212   1.1    jruoho 
    213   1.1    jruoho 	ATF_CHECK(isnan(cos(x)) != 0);
    214   1.1    jruoho }
    215   1.1    jruoho 
    216   1.1    jruoho ATF_TC(cos_inf_pos);
    217   1.1    jruoho ATF_TC_HEAD(cos_inf_pos, tc)
    218   1.1    jruoho {
    219   1.1    jruoho 	atf_tc_set_md_var(tc, "descr", "Test cos(+Inf) == NaN");
    220   1.1    jruoho }
    221   1.1    jruoho 
    222   1.1    jruoho ATF_TC_BODY(cos_inf_pos, tc)
    223   1.1    jruoho {
    224   1.1    jruoho 	const double x = 1.0L / 0.0L;
    225   1.1    jruoho 
    226   1.1    jruoho 	ATF_CHECK(isnan(cos(x)) != 0);
    227   1.1    jruoho }
    228   1.1    jruoho 
    229   1.1    jruoho ATF_TC(cos_zero_neg);
    230   1.1    jruoho ATF_TC_HEAD(cos_zero_neg, tc)
    231   1.1    jruoho {
    232   1.1    jruoho 	atf_tc_set_md_var(tc, "descr", "Test cos(-0.0) == 1.0");
    233   1.1    jruoho }
    234   1.1    jruoho 
    235   1.1    jruoho ATF_TC_BODY(cos_zero_neg, tc)
    236   1.1    jruoho {
    237   1.1    jruoho 	const double x = -0.0L;
    238   1.1    jruoho 
    239   1.1    jruoho 	ATF_CHECK(cos(x) == 1.0);
    240   1.1    jruoho }
    241   1.1    jruoho 
    242   1.1    jruoho ATF_TC(cos_zero_pos);
    243   1.1    jruoho ATF_TC_HEAD(cos_zero_pos, tc)
    244   1.1    jruoho {
    245   1.1    jruoho 	atf_tc_set_md_var(tc, "descr", "Test cos(+0.0) == 1.0");
    246   1.1    jruoho }
    247   1.1    jruoho 
    248   1.1    jruoho ATF_TC_BODY(cos_zero_pos, tc)
    249   1.1    jruoho {
    250   1.1    jruoho 	const double x = 0.0L;
    251   1.1    jruoho 
    252   1.1    jruoho 	ATF_CHECK(cos(x) == 1.0);
    253   1.1    jruoho }
    254   1.1    jruoho 
    255   1.1    jruoho /*
    256   1.1    jruoho  * cosf(3)
    257   1.1    jruoho  */
    258   1.1    jruoho ATF_TC(cosf_angles);
    259   1.1    jruoho ATF_TC_HEAD(cosf_angles, tc)
    260   1.1    jruoho {
    261   1.1    jruoho 	atf_tc_set_md_var(tc, "descr", "Test some selected angles");
    262   1.1    jruoho }
    263   1.1    jruoho 
    264   1.1    jruoho ATF_TC_BODY(cosf_angles, tc)
    265   1.1    jruoho {
    266   1.5  riastrad 	const float eps = FLT_EPSILON;
    267   1.1    jruoho 	size_t i;
    268   1.1    jruoho 
    269   1.1    jruoho 	for (i = 0; i < __arraycount(angles); i++) {
    270   1.5  riastrad 		int deg = angles[i].angle;
    271   1.5  riastrad 		float theta = angles[i].x;
    272   1.5  riastrad 		float cos_theta = angles[i].fy;
    273   1.5  riastrad 
    274   1.9      maya 		/*
    275   1.9      maya 		 * Force rounding to float even if FLT_EVAL_METHOD=2,
    276   1.9      maya 		 * as is the case on i386.
    277   1.9      maya 		 *
    278   1.9      maya 		 * The volatile should not be necessary, by C99 Sec.
    279   1.9      maya 		 * 5.2.4.2.2. para. 8 on p. 24 which specifies that
    280   1.9      maya 		 * assignment and cast remove all extra range and precision,
    281   1.9      maya 		 * but seems to be needed to work around a compiler bug.
    282   1.9      maya 		 */
    283   1.9      maya 		volatile float result = cosf(theta);
    284   1.9      maya 
    285   1.5  riastrad 		if (cos_theta == 999)
    286   1.5  riastrad 			cos_theta = angles[i].y;
    287   1.5  riastrad 
    288   1.5  riastrad 		assert(cos_theta != 0);
    289   1.9      maya 		if (!(fabsf((result - cos_theta)/cos_theta) <= eps)) {
    290   1.7  riastrad 			atf_tc_fail_nonfatal("cosf(%d deg = %.8g) = %.8g"
    291   1.9      maya 			    " != %.8g", deg, theta, result, cos_theta);
    292   1.5  riastrad 		}
    293   1.1    jruoho 	}
    294   1.1    jruoho }
    295   1.1    jruoho 
    296   1.1    jruoho ATF_TC(cosf_nan);
    297   1.1    jruoho ATF_TC_HEAD(cosf_nan, tc)
    298   1.1    jruoho {
    299   1.1    jruoho 	atf_tc_set_md_var(tc, "descr", "Test cosf(NaN) == NaN");
    300   1.1    jruoho }
    301   1.1    jruoho 
    302   1.1    jruoho ATF_TC_BODY(cosf_nan, tc)
    303   1.1    jruoho {
    304   1.1    jruoho 	const float x = 0.0L / 0.0L;
    305   1.1    jruoho 
    306   1.1    jruoho 	ATF_CHECK(isnan(x) != 0);
    307   1.1    jruoho 	ATF_CHECK(isnan(cosf(x)) != 0);
    308   1.1    jruoho }
    309   1.1    jruoho 
    310   1.1    jruoho ATF_TC(cosf_inf_neg);
    311   1.1    jruoho ATF_TC_HEAD(cosf_inf_neg, tc)
    312   1.1    jruoho {
    313   1.1    jruoho 	atf_tc_set_md_var(tc, "descr", "Test cosf(-Inf) == NaN");
    314   1.1    jruoho }
    315   1.1    jruoho 
    316   1.1    jruoho ATF_TC_BODY(cosf_inf_neg, tc)
    317   1.1    jruoho {
    318   1.1    jruoho 	const float x = -1.0L / 0.0L;
    319   1.1    jruoho 
    320   1.3    jruoho 	if (isnan(cosf(x)) == 0) {
    321   1.3    jruoho 		atf_tc_expect_fail("PR lib/45362");
    322   1.3    jruoho 		atf_tc_fail("cosf(-Inf) != NaN");
    323   1.3    jruoho 	}
    324   1.1    jruoho }
    325   1.1    jruoho 
    326   1.1    jruoho ATF_TC(cosf_inf_pos);
    327   1.1    jruoho ATF_TC_HEAD(cosf_inf_pos, tc)
    328   1.1    jruoho {
    329   1.1    jruoho 	atf_tc_set_md_var(tc, "descr", "Test cosf(+Inf) == NaN");
    330   1.1    jruoho }
    331   1.1    jruoho 
    332   1.1    jruoho ATF_TC_BODY(cosf_inf_pos, tc)
    333   1.1    jruoho {
    334   1.1    jruoho 	const float x = 1.0L / 0.0L;
    335   1.1    jruoho 
    336   1.3    jruoho 	if (isnan(cosf(x)) == 0) {
    337   1.3    jruoho 		atf_tc_expect_fail("PR lib/45362");
    338   1.3    jruoho 		atf_tc_fail("cosf(+Inf) != NaN");
    339   1.3    jruoho 	}
    340   1.1    jruoho }
    341   1.1    jruoho 
    342   1.1    jruoho 
    343   1.1    jruoho ATF_TC(cosf_zero_neg);
    344   1.1    jruoho ATF_TC_HEAD(cosf_zero_neg, tc)
    345   1.1    jruoho {
    346   1.1    jruoho 	atf_tc_set_md_var(tc, "descr", "Test cosf(-0.0) == 1.0");
    347   1.1    jruoho }
    348   1.1    jruoho 
    349   1.1    jruoho ATF_TC_BODY(cosf_zero_neg, tc)
    350   1.1    jruoho {
    351   1.1    jruoho 	const float x = -0.0L;
    352   1.1    jruoho 
    353   1.1    jruoho 	ATF_CHECK(cosf(x) == 1.0);
    354   1.1    jruoho }
    355   1.1    jruoho 
    356   1.1    jruoho ATF_TC(cosf_zero_pos);
    357   1.1    jruoho ATF_TC_HEAD(cosf_zero_pos, tc)
    358   1.1    jruoho {
    359   1.1    jruoho 	atf_tc_set_md_var(tc, "descr", "Test cosf(+0.0) == 1.0");
    360   1.1    jruoho }
    361   1.1    jruoho 
    362   1.1    jruoho ATF_TC_BODY(cosf_zero_pos, tc)
    363   1.1    jruoho {
    364   1.1    jruoho 	const float x = 0.0L;
    365   1.1    jruoho 
    366   1.1    jruoho 	ATF_CHECK(cosf(x) == 1.0);
    367   1.1    jruoho }
    368   1.1    jruoho 
    369   1.1    jruoho ATF_TP_ADD_TCS(tp)
    370   1.1    jruoho {
    371  1.10  riastrad 
    372   1.8      maya 	ATF_TP_ADD_TC(tp, cosl_angles);
    373   1.8      maya 	ATF_TP_ADD_TC(tp, cosl_nan);
    374   1.8      maya 	ATF_TP_ADD_TC(tp, cosl_inf_neg);
    375   1.8      maya 	ATF_TP_ADD_TC(tp, cosl_inf_pos);
    376   1.8      maya 	ATF_TP_ADD_TC(tp, cosl_zero_neg);
    377   1.8      maya 	ATF_TP_ADD_TC(tp, cosl_zero_pos);
    378   1.1    jruoho 
    379   1.1    jruoho 	ATF_TP_ADD_TC(tp, cos_angles);
    380   1.1    jruoho 	ATF_TP_ADD_TC(tp, cos_nan);
    381   1.1    jruoho 	ATF_TP_ADD_TC(tp, cos_inf_neg);
    382   1.1    jruoho 	ATF_TP_ADD_TC(tp, cos_inf_pos);
    383   1.1    jruoho 	ATF_TP_ADD_TC(tp, cos_zero_neg);
    384   1.1    jruoho 	ATF_TP_ADD_TC(tp, cos_zero_pos);
    385   1.1    jruoho 
    386   1.1    jruoho 	ATF_TP_ADD_TC(tp, cosf_angles);
    387   1.1    jruoho 	ATF_TP_ADD_TC(tp, cosf_nan);
    388   1.1    jruoho 	ATF_TP_ADD_TC(tp, cosf_inf_neg);
    389   1.1    jruoho 	ATF_TP_ADD_TC(tp, cosf_inf_pos);
    390   1.1    jruoho 	ATF_TP_ADD_TC(tp, cosf_zero_neg);
    391   1.1    jruoho 	ATF_TP_ADD_TC(tp, cosf_zero_pos);
    392   1.1    jruoho 
    393   1.1    jruoho 	return atf_no_error();
    394   1.1    jruoho }
    395