1 /* $NetBSD: t_sqrt.c,v 1.5 2013/11/22 17:19:14 martin 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.5 2013/11/22 17:19:14 martin 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 #ifndef __vax__ 51 const double x = 0.0L / 0.0L; 52 53 ATF_CHECK(isnan(x) != 0); 54 ATF_CHECK(isnan(sqrt(x)) != 0); 55 #endif 56 } 57 58 ATF_TC(sqrt_pow); 59 ATF_TC_HEAD(sqrt_pow, tc) 60 { 61 atf_tc_set_md_var(tc, "descr", "Test sqrt(3) vs. pow(3)"); 62 } 63 64 ATF_TC_BODY(sqrt_pow, tc) 65 { 66 #ifndef __vax__ 67 const double x[] = { 0.0, 0.005, 1.0, 99.0, 123.123, 9999.9999 }; 68 const double eps = 1.0e-40; 69 double y, z; 70 size_t i; 71 72 for (i = 0; i < __arraycount(x); i++) { 73 74 y = sqrt(x[i]); 75 z = pow(x[i], 1.0 / 2.0); 76 77 if (fabs(y - z) > eps) 78 atf_tc_fail_nonfatal("sqrt(%0.03f) != " 79 "pow(%0.03f, 1/2)\n", x[i], x[i]); 80 } 81 #endif 82 } 83 84 ATF_TC(sqrt_inf_neg); 85 ATF_TC_HEAD(sqrt_inf_neg, tc) 86 { 87 atf_tc_set_md_var(tc, "descr", "Test sqrt(-Inf) == NaN"); 88 } 89 90 ATF_TC_BODY(sqrt_inf_neg, tc) 91 { 92 #ifndef __vax__ 93 const double x = -1.0L / 0.0L; 94 double y = sqrt(x); 95 96 ATF_CHECK(isnan(y) != 0); 97 #endif 98 } 99 100 ATF_TC(sqrt_inf_pos); 101 ATF_TC_HEAD(sqrt_inf_pos, tc) 102 { 103 atf_tc_set_md_var(tc, "descr", "Test sqrt(+Inf) == +Inf"); 104 } 105 106 ATF_TC_BODY(sqrt_inf_pos, tc) 107 { 108 #ifndef __vax__ 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 #endif 115 } 116 117 ATF_TC(sqrt_zero_neg); 118 ATF_TC_HEAD(sqrt_zero_neg, tc) 119 { 120 atf_tc_set_md_var(tc, "descr", "Test sqrt(-0.0) == -0.0"); 121 } 122 123 ATF_TC_BODY(sqrt_zero_neg, tc) 124 { 125 #ifndef __vax__ 126 const double x = -0.0L; 127 double y = sqrt(x); 128 129 if (fabs(y) > 0.0 || signbit(y) == 0) 130 atf_tc_fail_nonfatal("sqrt(-0.0) != -0.0"); 131 #endif 132 } 133 134 ATF_TC(sqrt_zero_pos); 135 ATF_TC_HEAD(sqrt_zero_pos, tc) 136 { 137 atf_tc_set_md_var(tc, "descr", "Test sqrt(+0.0) == +0.0"); 138 } 139 140 ATF_TC_BODY(sqrt_zero_pos, tc) 141 { 142 #ifndef __vax__ 143 const double x = 0.0L; 144 double y = sqrt(x); 145 146 if (fabs(y) > 0.0 || signbit(y) != 0) 147 atf_tc_fail_nonfatal("sqrt(+0.0) != +0.0"); 148 #endif 149 } 150 151 /* 152 * sqrtf(3) 153 */ 154 ATF_TC(sqrtf_nan); 155 ATF_TC_HEAD(sqrtf_nan, tc) 156 { 157 atf_tc_set_md_var(tc, "descr", "Test sqrtf(NaN) == NaN"); 158 } 159 160 ATF_TC_BODY(sqrtf_nan, tc) 161 { 162 #ifndef __vax__ 163 const float x = 0.0L / 0.0L; 164 165 ATF_CHECK(isnan(x) != 0); 166 ATF_CHECK(isnan(sqrtf(x)) != 0); 167 #endif 168 } 169 170 ATF_TC(sqrtf_powf); 171 ATF_TC_HEAD(sqrtf_powf, tc) 172 { 173 atf_tc_set_md_var(tc, "descr", "Test sqrtf(3) vs. powf(3)"); 174 } 175 176 ATF_TC_BODY(sqrtf_powf, tc) 177 { 178 #ifndef __vax__ 179 const float x[] = { 0.0, 0.005, 1.0, 99.0, 123.123, 9999.9999 }; 180 const float eps = 1.0e-30; 181 volatile float y, z; 182 size_t i; 183 184 for (i = 0; i < __arraycount(x); i++) { 185 186 y = sqrtf(x[i]); 187 z = powf(x[i], 1.0 / 2.0); 188 189 if (fabsf(y - z) > eps) 190 atf_tc_fail_nonfatal("sqrtf(%0.03f) != " 191 "powf(%0.03f, 1/2)\n", x[i], x[i]); 192 } 193 #endif 194 } 195 196 ATF_TC(sqrtf_inf_neg); 197 ATF_TC_HEAD(sqrtf_inf_neg, tc) 198 { 199 atf_tc_set_md_var(tc, "descr", "Test sqrtf(-Inf) == NaN"); 200 } 201 202 ATF_TC_BODY(sqrtf_inf_neg, tc) 203 { 204 #ifndef __vax__ 205 const float x = -1.0L / 0.0L; 206 float y = sqrtf(x); 207 208 ATF_CHECK(isnan(y) != 0); 209 #endif 210 } 211 212 ATF_TC(sqrtf_inf_pos); 213 ATF_TC_HEAD(sqrtf_inf_pos, tc) 214 { 215 atf_tc_set_md_var(tc, "descr", "Test sqrtf(+Inf) == +Inf"); 216 } 217 218 ATF_TC_BODY(sqrtf_inf_pos, tc) 219 { 220 #ifndef __vax__ 221 const float x = 1.0L / 0.0L; 222 float y = sqrtf(x); 223 224 ATF_CHECK(isinf(y) != 0); 225 ATF_CHECK(signbit(y) == 0); 226 #endif 227 } 228 229 ATF_TC(sqrtf_zero_neg); 230 ATF_TC_HEAD(sqrtf_zero_neg, tc) 231 { 232 atf_tc_set_md_var(tc, "descr", "Test sqrtf(-0.0) == -0.0"); 233 } 234 235 ATF_TC_BODY(sqrtf_zero_neg, tc) 236 { 237 #ifndef __vax__ 238 const float x = -0.0L; 239 float y = sqrtf(x); 240 241 if (fabsf(y) > 0.0 || signbit(y) == 0) 242 atf_tc_fail_nonfatal("sqrtf(-0.0) != -0.0"); 243 #endif 244 } 245 246 ATF_TC(sqrtf_zero_pos); 247 ATF_TC_HEAD(sqrtf_zero_pos, tc) 248 { 249 atf_tc_set_md_var(tc, "descr", "Test sqrtf(+0.0) == +0.0"); 250 } 251 252 ATF_TC_BODY(sqrtf_zero_pos, tc) 253 { 254 #ifndef __vax__ 255 const float x = 0.0L; 256 float y = sqrtf(x); 257 258 if (fabsf(y) > 0.0 || signbit(y) != 0) 259 atf_tc_fail_nonfatal("sqrtf(+0.0) != +0.0"); 260 #endif 261 } 262 263 /* 264 * sqrtl(3) 265 */ 266 ATF_TC(sqrtl_nan); 267 ATF_TC_HEAD(sqrtl_nan, tc) 268 { 269 atf_tc_set_md_var(tc, "descr", "Test sqrtl(NaN) == NaN"); 270 } 271 272 ATF_TC_BODY(sqrtl_nan, tc) 273 { 274 #ifndef __vax__ 275 const long double x = 0.0L / 0.0L; 276 277 ATF_CHECK(isnan(x) != 0); 278 ATF_CHECK(isnan(sqrtl(x)) != 0); 279 #endif 280 } 281 282 ATF_TC(sqrtl_powl); 283 ATF_TC_HEAD(sqrtl_powl, tc) 284 { 285 atf_tc_set_md_var(tc, "descr", "Test sqrtl(3) vs. powl(3)"); 286 } 287 288 ATF_TC_BODY(sqrtl_powl, tc) 289 { 290 #ifndef __vax__ 291 const long double x[] = { 0.0, 0.005, 1.0, 99.0, 123.123, 9999.9999 }; 292 const long double eps = 5.0*DBL_EPSILON; /* XXX powl == pow for now */ 293 volatile long double y, z; 294 size_t i; 295 296 for (i = 0; i < __arraycount(x); i++) { 297 298 y = sqrtl(x[i]); 299 z = powl(x[i], 1.0 / 2.0); 300 301 if (fabsl(y - z) > eps) 302 atf_tc_fail_nonfatal("sqrtl(%0.03Lf) != " 303 "powl(%0.03Lf, 1/2)\n", x[i], x[i]); 304 } 305 #endif 306 } 307 308 ATF_TC(sqrtl_inf_neg); 309 ATF_TC_HEAD(sqrtl_inf_neg, tc) 310 { 311 atf_tc_set_md_var(tc, "descr", "Test sqrtl(-Inf) == NaN"); 312 } 313 314 ATF_TC_BODY(sqrtl_inf_neg, tc) 315 { 316 #ifndef __vax__ 317 const long double x = -1.0L / 0.0L; 318 long double y = sqrtl(x); 319 320 ATF_CHECK(isnan(y) != 0); 321 #endif 322 } 323 324 ATF_TC(sqrtl_inf_pos); 325 ATF_TC_HEAD(sqrtl_inf_pos, tc) 326 { 327 atf_tc_set_md_var(tc, "descr", "Test sqrtl(+Inf) == +Inf"); 328 } 329 330 ATF_TC_BODY(sqrtl_inf_pos, tc) 331 { 332 #ifndef __vax__ 333 const long double x = 1.0L / 0.0L; 334 long double y = sqrtl(x); 335 336 ATF_CHECK(isinf(y) != 0); 337 ATF_CHECK(signbit(y) == 0); 338 #endif 339 } 340 341 ATF_TC(sqrtl_zero_neg); 342 ATF_TC_HEAD(sqrtl_zero_neg, tc) 343 { 344 atf_tc_set_md_var(tc, "descr", "Test sqrtl(-0.0) == -0.0"); 345 } 346 347 ATF_TC_BODY(sqrtl_zero_neg, tc) 348 { 349 #ifndef __vax__ 350 const long double x = -0.0L; 351 long double y = sqrtl(x); 352 353 if (fabsl(y) > 0.0 || signbit(y) == 0) 354 atf_tc_fail_nonfatal("sqrtl(-0.0) != -0.0"); 355 #endif 356 } 357 358 ATF_TC(sqrtl_zero_pos); 359 ATF_TC_HEAD(sqrtl_zero_pos, tc) 360 { 361 atf_tc_set_md_var(tc, "descr", "Test sqrtl(+0.0) == +0.0"); 362 } 363 364 ATF_TC_BODY(sqrtl_zero_pos, tc) 365 { 366 #ifndef __vax__ 367 const long double x = 0.0L; 368 long double y = sqrtl(x); 369 370 if (fabsl(y) > 0.0 || signbit(y) != 0) 371 atf_tc_fail_nonfatal("sqrtl(+0.0) != +0.0"); 372 #endif 373 } 374 375 ATF_TP_ADD_TCS(tp) 376 { 377 378 ATF_TP_ADD_TC(tp, sqrt_nan); 379 ATF_TP_ADD_TC(tp, sqrt_pow); 380 ATF_TP_ADD_TC(tp, sqrt_inf_neg); 381 ATF_TP_ADD_TC(tp, sqrt_inf_pos); 382 ATF_TP_ADD_TC(tp, sqrt_zero_neg); 383 ATF_TP_ADD_TC(tp, sqrt_zero_pos); 384 385 ATF_TP_ADD_TC(tp, sqrtf_nan); 386 ATF_TP_ADD_TC(tp, sqrtf_powf); 387 ATF_TP_ADD_TC(tp, sqrtf_inf_neg); 388 ATF_TP_ADD_TC(tp, sqrtf_inf_pos); 389 ATF_TP_ADD_TC(tp, sqrtf_zero_neg); 390 ATF_TP_ADD_TC(tp, sqrtf_zero_pos); 391 392 ATF_TP_ADD_TC(tp, sqrtl_nan); 393 ATF_TP_ADD_TC(tp, sqrtl_powl); 394 ATF_TP_ADD_TC(tp, sqrtl_inf_neg); 395 ATF_TP_ADD_TC(tp, sqrtl_inf_pos); 396 ATF_TP_ADD_TC(tp, sqrtl_zero_neg); 397 ATF_TP_ADD_TC(tp, sqrtl_zero_pos); 398 399 return atf_no_error(); 400 } 401