Home | History | Annotate | Line # | Download | only in libm
      1 /* $NetBSD: t_sqrt.c,v 1.8 2018/11/07 03:59:36 riastradh Exp $ */
      2 
      3 /*-
      4  * Copyright (c) 2011 The NetBSD Foundation, Inc.
      5  * All rights reserved.
      6  *
      7  * This code is derived from software contributed to The NetBSD Foundation
      8  * by Jukka Ruohonen.
      9  *
     10  * Redistribution and use in source and binary forms, with or without
     11  * modification, are permitted provided that the following conditions
     12  * are met:
     13  * 1. Redistributions of source code must retain the above copyright
     14  *    notice, this list of conditions and the following disclaimer.
     15  * 2. Redistributions in binary form must reproduce the above copyright
     16  *    notice, this list of conditions and the following disclaimer in the
     17  *    documentation and/or other materials provided with the distribution.
     18  *
     19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     29  * POSSIBILITY OF SUCH DAMAGE.
     30  */
     31 #include <sys/cdefs.h>
     32 __RCSID("$NetBSD: t_sqrt.c,v 1.8 2018/11/07 03:59:36 riastradh Exp $");
     33 
     34 #include <atf-c.h>
     35 #include <math.h>
     36 #include <float.h>
     37 #include <stdio.h>
     38 
     39 /*
     40  * sqrt(3)
     41  */
     42 ATF_TC(sqrt_nan);
     43 ATF_TC_HEAD(sqrt_nan, tc)
     44 {
     45 	atf_tc_set_md_var(tc, "descr", "Test sqrt(NaN) == NaN");
     46 }
     47 
     48 ATF_TC_BODY(sqrt_nan, tc)
     49 {
     50 	const double x = 0.0L / 0.0L;
     51 
     52 	ATF_CHECK(isnan(x) != 0);
     53 	ATF_CHECK(isnan(sqrt(x)) != 0);
     54 }
     55 
     56 ATF_TC(sqrt_pow);
     57 ATF_TC_HEAD(sqrt_pow, tc)
     58 {
     59 	atf_tc_set_md_var(tc, "descr", "Test sqrt(3) vs. pow(3)");
     60 }
     61 
     62 ATF_TC_BODY(sqrt_pow, tc)
     63 {
     64 	const double x[] = { 0.0, 0.005, 1.0, 99.0, 123.123, 9999.9999 };
     65 	const double eps = DBL_EPSILON;
     66 	size_t i;
     67 
     68 	for (i = 0; i < __arraycount(x); i++) {
     69 		double x_sqrt = sqrt(x[i]);
     70 		double x_pow12 = pow(x[i], 1.0 / 2.0);
     71 		bool ok;
     72 
     73 		if (x[i] == 0) {
     74 			ok = (x_sqrt == x_pow12);
     75 		} else {
     76 			ok = (fabs((x_sqrt - x_pow12)/x_sqrt) <= eps);
     77 		}
     78 
     79 		if (!ok) {
     80 			atf_tc_fail_nonfatal("sqrt(%.17g) = %.17g != "
     81 			    "pow(%.17g, 1/2) = %.17g\n",
     82 			    x[i], x_sqrt, x[i], x_pow12);
     83 		}
     84 	}
     85 }
     86 
     87 ATF_TC(sqrt_inf_neg);
     88 ATF_TC_HEAD(sqrt_inf_neg, tc)
     89 {
     90 	atf_tc_set_md_var(tc, "descr", "Test sqrt(-Inf) == NaN");
     91 }
     92 
     93 ATF_TC_BODY(sqrt_inf_neg, tc)
     94 {
     95 	const double x = -1.0L / 0.0L;
     96 	double y = sqrt(x);
     97 
     98 	ATF_CHECK(isnan(y) != 0);
     99 }
    100 
    101 ATF_TC(sqrt_inf_pos);
    102 ATF_TC_HEAD(sqrt_inf_pos, tc)
    103 {
    104 	atf_tc_set_md_var(tc, "descr", "Test sqrt(+Inf) == +Inf");
    105 }
    106 
    107 ATF_TC_BODY(sqrt_inf_pos, tc)
    108 {
    109 	const double x = 1.0L / 0.0L;
    110 	double y = sqrt(x);
    111 
    112 	ATF_CHECK(isinf(y) != 0);
    113 	ATF_CHECK(signbit(y) == 0);
    114 }
    115 
    116 ATF_TC(sqrt_zero_neg);
    117 ATF_TC_HEAD(sqrt_zero_neg, tc)
    118 {
    119 	atf_tc_set_md_var(tc, "descr", "Test sqrt(-0.0) == -0.0");
    120 }
    121 
    122 ATF_TC_BODY(sqrt_zero_neg, tc)
    123 {
    124 	const double x = -0.0L;
    125 	double y = sqrt(x);
    126 
    127 	if (fabs(y) > 0.0 || signbit(y) == 0)
    128 		atf_tc_fail_nonfatal("sqrt(-0.0) != -0.0");
    129 }
    130 
    131 ATF_TC(sqrt_zero_pos);
    132 ATF_TC_HEAD(sqrt_zero_pos, tc)
    133 {
    134 	atf_tc_set_md_var(tc, "descr", "Test sqrt(+0.0) == +0.0");
    135 }
    136 
    137 ATF_TC_BODY(sqrt_zero_pos, tc)
    138 {
    139 	const double x = 0.0L;
    140 	double y = sqrt(x);
    141 
    142 	if (fabs(y) > 0.0 || signbit(y) != 0)
    143 		atf_tc_fail_nonfatal("sqrt(+0.0) != +0.0");
    144 }
    145 
    146 /*
    147  * sqrtf(3)
    148  */
    149 ATF_TC(sqrtf_nan);
    150 ATF_TC_HEAD(sqrtf_nan, tc)
    151 {
    152 	atf_tc_set_md_var(tc, "descr", "Test sqrtf(NaN) == NaN");
    153 }
    154 
    155 ATF_TC_BODY(sqrtf_nan, tc)
    156 {
    157 	const float x = 0.0L / 0.0L;
    158 
    159 	ATF_CHECK(isnan(x) != 0);
    160 	ATF_CHECK(isnan(sqrtf(x)) != 0);
    161 }
    162 
    163 ATF_TC(sqrtf_powf);
    164 ATF_TC_HEAD(sqrtf_powf, tc)
    165 {
    166 	atf_tc_set_md_var(tc, "descr", "Test sqrtf(3) vs. powf(3)");
    167 }
    168 
    169 ATF_TC_BODY(sqrtf_powf, tc)
    170 {
    171 	const float x[] = { 0.0, 0.005, 1.0, 99.0, 123.123, 9999.9999 };
    172 	const float eps = FLT_EPSILON;
    173 	size_t i;
    174 
    175 	for (i = 0; i < __arraycount(x); i++) {
    176 		float x_sqrt = sqrtf(x[i]);
    177 		float x_pow12 = powf(x[i], 1.0 / 2.0);
    178 		bool ok;
    179 
    180 		if (x[i] == 0) {
    181 			ok = (x_sqrt == x_pow12);
    182 		} else {
    183 			ok = (fabsf((x_sqrt - x_pow12)/x_sqrt) <= eps);
    184 		}
    185 
    186 		if (!ok) {
    187 			atf_tc_fail_nonfatal("sqrtf(%.8g) = %.8g != "
    188 			    "powf(%.8g, 1/2) = %.8g\n",
    189 			    (double)x[i], (double)x_sqrt,
    190 			    (double)x[i], (double)x_pow12);
    191 		}
    192 	}
    193 }
    194 
    195 ATF_TC(sqrtf_inf_neg);
    196 ATF_TC_HEAD(sqrtf_inf_neg, tc)
    197 {
    198 	atf_tc_set_md_var(tc, "descr", "Test sqrtf(-Inf) == NaN");
    199 }
    200 
    201 ATF_TC_BODY(sqrtf_inf_neg, tc)
    202 {
    203 	const float x = -1.0L / 0.0L;
    204 	float y = sqrtf(x);
    205 
    206 	ATF_CHECK(isnan(y) != 0);
    207 }
    208 
    209 ATF_TC(sqrtf_inf_pos);
    210 ATF_TC_HEAD(sqrtf_inf_pos, tc)
    211 {
    212 	atf_tc_set_md_var(tc, "descr", "Test sqrtf(+Inf) == +Inf");
    213 }
    214 
    215 ATF_TC_BODY(sqrtf_inf_pos, tc)
    216 {
    217 	const float x = 1.0L / 0.0L;
    218 	float y = sqrtf(x);
    219 
    220 	ATF_CHECK(isinf(y) != 0);
    221 	ATF_CHECK(signbit(y) == 0);
    222 }
    223 
    224 ATF_TC(sqrtf_zero_neg);
    225 ATF_TC_HEAD(sqrtf_zero_neg, tc)
    226 {
    227 	atf_tc_set_md_var(tc, "descr", "Test sqrtf(-0.0) == -0.0");
    228 }
    229 
    230 ATF_TC_BODY(sqrtf_zero_neg, tc)
    231 {
    232 	const float x = -0.0L;
    233 	float y = sqrtf(x);
    234 
    235 	if (fabsf(y) > 0.0 || signbit(y) == 0)
    236 		atf_tc_fail_nonfatal("sqrtf(-0.0) != -0.0");
    237 }
    238 
    239 ATF_TC(sqrtf_zero_pos);
    240 ATF_TC_HEAD(sqrtf_zero_pos, tc)
    241 {
    242 	atf_tc_set_md_var(tc, "descr", "Test sqrtf(+0.0) == +0.0");
    243 }
    244 
    245 ATF_TC_BODY(sqrtf_zero_pos, tc)
    246 {
    247 	const float x = 0.0L;
    248 	float y = sqrtf(x);
    249 
    250 	if (fabsf(y) > 0.0 || signbit(y) != 0)
    251 		atf_tc_fail_nonfatal("sqrtf(+0.0) != +0.0");
    252 }
    253 
    254 /*
    255  * sqrtl(3)
    256  */
    257 ATF_TC(sqrtl_nan);
    258 ATF_TC_HEAD(sqrtl_nan, tc)
    259 {
    260 	atf_tc_set_md_var(tc, "descr", "Test sqrtl(NaN) == NaN");
    261 }
    262 
    263 ATF_TC_BODY(sqrtl_nan, tc)
    264 {
    265 	const long double x = 0.0L / 0.0L;
    266 
    267 	ATF_CHECK(isnan(x) != 0);
    268 	ATF_CHECK(isnan(sqrtl(x)) != 0);
    269 }
    270 
    271 ATF_TC(sqrtl_powl);
    272 ATF_TC_HEAD(sqrtl_powl, tc)
    273 {
    274 	atf_tc_set_md_var(tc, "descr", "Test sqrtl(3) vs. powl(3)");
    275 }
    276 
    277 ATF_TC_BODY(sqrtl_powl, tc)
    278 {
    279 	const long double x[] = { 0.0, 0.005, 1.0, 99.0, 123.123, 9999.9999 };
    280 	const long double eps = DBL_EPSILON; /* XXX powl == pow for now */
    281 	size_t i;
    282 
    283 	for (i = 0; i < __arraycount(x); i++) {
    284 		long double x_sqrt = sqrtl(x[i]);
    285 		long double x_pow12 = powl(x[i], 1.0 / 2.0);
    286 		bool ok;
    287 
    288 		if (x[i] == 0) {
    289 			ok = (x_sqrt == x_pow12);
    290 		} else {
    291 			ok = (fabsl((x_sqrt - x_pow12)/x_sqrt) <= eps);
    292 		}
    293 
    294 		if (!ok) {
    295 			atf_tc_fail_nonfatal("sqrtl(%.35Lg) = %.35Lg != "
    296 			    "powl(%.35Lg, 1/2) = %.35Lg\n",
    297 			    x[i], x_sqrt, x[i], x_pow12);
    298 		}
    299 	}
    300 }
    301 
    302 ATF_TC(sqrtl_inf_neg);
    303 ATF_TC_HEAD(sqrtl_inf_neg, tc)
    304 {
    305 	atf_tc_set_md_var(tc, "descr", "Test sqrtl(-Inf) == NaN");
    306 }
    307 
    308 ATF_TC_BODY(sqrtl_inf_neg, tc)
    309 {
    310 	const long double x = -1.0L / 0.0L;
    311 	long double y = sqrtl(x);
    312 
    313 	ATF_CHECK(isnan(y) != 0);
    314 }
    315 
    316 ATF_TC(sqrtl_inf_pos);
    317 ATF_TC_HEAD(sqrtl_inf_pos, tc)
    318 {
    319 	atf_tc_set_md_var(tc, "descr", "Test sqrtl(+Inf) == +Inf");
    320 }
    321 
    322 ATF_TC_BODY(sqrtl_inf_pos, tc)
    323 {
    324 	const long double x = 1.0L / 0.0L;
    325 	long double y = sqrtl(x);
    326 
    327 	ATF_CHECK(isinf(y) != 0);
    328 	ATF_CHECK(signbit(y) == 0);
    329 }
    330 
    331 ATF_TC(sqrtl_zero_neg);
    332 ATF_TC_HEAD(sqrtl_zero_neg, tc)
    333 {
    334 	atf_tc_set_md_var(tc, "descr", "Test sqrtl(-0.0) == -0.0");
    335 }
    336 
    337 ATF_TC_BODY(sqrtl_zero_neg, tc)
    338 {
    339 	const long double x = -0.0L;
    340 	long double y = sqrtl(x);
    341 
    342 	if (fabsl(y) > 0.0 || signbit(y) == 0)
    343 		atf_tc_fail_nonfatal("sqrtl(-0.0) != -0.0");
    344 }
    345 
    346 ATF_TC(sqrtl_zero_pos);
    347 ATF_TC_HEAD(sqrtl_zero_pos, tc)
    348 {
    349 	atf_tc_set_md_var(tc, "descr", "Test sqrtl(+0.0) == +0.0");
    350 }
    351 
    352 ATF_TC_BODY(sqrtl_zero_pos, tc)
    353 {
    354 	const long double x = 0.0L;
    355 	long double y = sqrtl(x);
    356 
    357 	if (fabsl(y) > 0.0 || signbit(y) != 0)
    358 		atf_tc_fail_nonfatal("sqrtl(+0.0) != +0.0");
    359 }
    360 
    361 ATF_TP_ADD_TCS(tp)
    362 {
    363 
    364 	ATF_TP_ADD_TC(tp, sqrt_nan);
    365 	ATF_TP_ADD_TC(tp, sqrt_pow);
    366 	ATF_TP_ADD_TC(tp, sqrt_inf_neg);
    367 	ATF_TP_ADD_TC(tp, sqrt_inf_pos);
    368 	ATF_TP_ADD_TC(tp, sqrt_zero_neg);
    369 	ATF_TP_ADD_TC(tp, sqrt_zero_pos);
    370 
    371 	ATF_TP_ADD_TC(tp, sqrtf_nan);
    372 	ATF_TP_ADD_TC(tp, sqrtf_powf);
    373 	ATF_TP_ADD_TC(tp, sqrtf_inf_neg);
    374 	ATF_TP_ADD_TC(tp, sqrtf_inf_pos);
    375 	ATF_TP_ADD_TC(tp, sqrtf_zero_neg);
    376 	ATF_TP_ADD_TC(tp, sqrtf_zero_pos);
    377 
    378 	ATF_TP_ADD_TC(tp, sqrtl_nan);
    379 	ATF_TP_ADD_TC(tp, sqrtl_powl);
    380 	ATF_TP_ADD_TC(tp, sqrtl_inf_neg);
    381 	ATF_TP_ADD_TC(tp, sqrtl_inf_pos);
    382 	ATF_TP_ADD_TC(tp, sqrtl_zero_neg);
    383 	ATF_TP_ADD_TC(tp, sqrtl_zero_pos);
    384 
    385 	return atf_no_error();
    386 }
    387