1 1.6 christos /* $NetBSD: t_cbrt.c,v 1.6 2024/04/03 01:52:28 christos 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 #include <sys/cdefs.h> 32 1.6 christos __RCSID("$NetBSD: t_cbrt.c,v 1.6 2024/04/03 01:52:28 christos Exp $"); 33 1.1 jruoho 34 1.1 jruoho #include <atf-c.h> 35 1.4 riastrad #include <float.h> 36 1.1 jruoho #include <math.h> 37 1.1 jruoho #include <stdio.h> 38 1.1 jruoho 39 1.1 jruoho /* 40 1.1 jruoho * cbrt(3) 41 1.1 jruoho */ 42 1.1 jruoho ATF_TC(cbrt_nan); 43 1.1 jruoho ATF_TC_HEAD(cbrt_nan, tc) 44 1.1 jruoho { 45 1.1 jruoho atf_tc_set_md_var(tc, "descr", "Test cbrt(NaN) == NaN"); 46 1.1 jruoho } 47 1.1 jruoho 48 1.1 jruoho ATF_TC_BODY(cbrt_nan, tc) 49 1.1 jruoho { 50 1.1 jruoho const double x = 0.0L / 0.0L; 51 1.1 jruoho 52 1.1 jruoho ATF_CHECK(isnan(x) != 0); 53 1.1 jruoho ATF_CHECK(isnan(cbrt(x)) != 0); 54 1.1 jruoho } 55 1.1 jruoho 56 1.1 jruoho ATF_TC(cbrt_pow); 57 1.1 jruoho ATF_TC_HEAD(cbrt_pow, tc) 58 1.1 jruoho { 59 1.1 jruoho atf_tc_set_md_var(tc, "descr", "Test cbrt(3) vs. pow(3)"); 60 1.1 jruoho } 61 1.1 jruoho 62 1.1 jruoho ATF_TC_BODY(cbrt_pow, tc) 63 1.1 jruoho { 64 1.1 jruoho const double x[] = { 0.0, 0.005, 1.0, 99.0, 123.123, 9999.0 }; 65 1.4 riastrad /* Neither cbrt nor pow is required to be correctly rounded. */ 66 1.4 riastrad const double eps = 2*DBL_EPSILON; 67 1.1 jruoho size_t i; 68 1.1 jruoho 69 1.1 jruoho for (i = 0; i < __arraycount(x); i++) { 70 1.4 riastrad double x_cbrt = cbrt(x[i]); 71 1.4 riastrad double x_pow13 = pow(x[i], 1.0 / 3.0); 72 1.4 riastrad bool ok; 73 1.4 riastrad 74 1.4 riastrad if (x[i] == 0) { 75 1.4 riastrad ok = (x_cbrt == x_pow13); 76 1.4 riastrad } else { 77 1.4 riastrad ok = (fabs((x_cbrt - x_pow13)/x_cbrt) <= eps); 78 1.4 riastrad } 79 1.4 riastrad 80 1.4 riastrad if (!ok) { 81 1.4 riastrad atf_tc_fail_nonfatal("cbrt(%.17g) = %.17g != " 82 1.4 riastrad "pow(%.17g, 1/3) = %.17g\n", 83 1.4 riastrad x[i], x_cbrt, x[i], x_pow13); 84 1.4 riastrad } 85 1.1 jruoho } 86 1.1 jruoho } 87 1.1 jruoho 88 1.1 jruoho ATF_TC(cbrt_inf_neg); 89 1.1 jruoho ATF_TC_HEAD(cbrt_inf_neg, tc) 90 1.1 jruoho { 91 1.1 jruoho atf_tc_set_md_var(tc, "descr", "Test cbrt(-Inf) == -Inf"); 92 1.1 jruoho } 93 1.1 jruoho 94 1.1 jruoho ATF_TC_BODY(cbrt_inf_neg, tc) 95 1.1 jruoho { 96 1.1 jruoho const double x = -1.0L / 0.0L; 97 1.1 jruoho double y = cbrt(x); 98 1.1 jruoho 99 1.1 jruoho ATF_CHECK(isinf(y) != 0); 100 1.1 jruoho ATF_CHECK(signbit(y) != 0); 101 1.1 jruoho } 102 1.1 jruoho 103 1.1 jruoho ATF_TC(cbrt_inf_pos); 104 1.1 jruoho ATF_TC_HEAD(cbrt_inf_pos, tc) 105 1.1 jruoho { 106 1.1 jruoho atf_tc_set_md_var(tc, "descr", "Test cbrt(+Inf) == +Inf"); 107 1.1 jruoho } 108 1.1 jruoho 109 1.1 jruoho ATF_TC_BODY(cbrt_inf_pos, tc) 110 1.1 jruoho { 111 1.1 jruoho const double x = 1.0L / 0.0L; 112 1.1 jruoho double y = cbrt(x); 113 1.1 jruoho 114 1.1 jruoho ATF_CHECK(isinf(y) != 0); 115 1.1 jruoho ATF_CHECK(signbit(y) == 0); 116 1.1 jruoho } 117 1.1 jruoho 118 1.1 jruoho ATF_TC(cbrt_zero_neg); 119 1.1 jruoho ATF_TC_HEAD(cbrt_zero_neg, tc) 120 1.1 jruoho { 121 1.1 jruoho atf_tc_set_md_var(tc, "descr", "Test cbrt(-0.0) == -0.0"); 122 1.1 jruoho } 123 1.1 jruoho 124 1.1 jruoho ATF_TC_BODY(cbrt_zero_neg, tc) 125 1.1 jruoho { 126 1.1 jruoho const double x = -0.0L; 127 1.1 jruoho double y = cbrt(x); 128 1.1 jruoho 129 1.1 jruoho if (fabs(y) > 0.0 || signbit(y) == 0) 130 1.1 jruoho atf_tc_fail_nonfatal("cbrt(-0.0) != -0.0"); 131 1.1 jruoho } 132 1.1 jruoho 133 1.1 jruoho ATF_TC(cbrt_zero_pos); 134 1.1 jruoho ATF_TC_HEAD(cbrt_zero_pos, tc) 135 1.1 jruoho { 136 1.1 jruoho atf_tc_set_md_var(tc, "descr", "Test cbrt(+0.0) == +0.0"); 137 1.1 jruoho } 138 1.1 jruoho 139 1.1 jruoho ATF_TC_BODY(cbrt_zero_pos, tc) 140 1.1 jruoho { 141 1.1 jruoho const double x = 0.0L; 142 1.1 jruoho double y = cbrt(x); 143 1.1 jruoho 144 1.1 jruoho if (fabs(y) > 0.0 || signbit(y) != 0) 145 1.1 jruoho atf_tc_fail_nonfatal("cbrt(+0.0) != +0.0"); 146 1.1 jruoho } 147 1.1 jruoho 148 1.1 jruoho /* 149 1.1 jruoho * cbrtf(3) 150 1.1 jruoho */ 151 1.1 jruoho ATF_TC(cbrtf_nan); 152 1.1 jruoho ATF_TC_HEAD(cbrtf_nan, tc) 153 1.1 jruoho { 154 1.1 jruoho atf_tc_set_md_var(tc, "descr", "Test cbrtf(NaN) == NaN"); 155 1.1 jruoho } 156 1.1 jruoho 157 1.1 jruoho ATF_TC_BODY(cbrtf_nan, tc) 158 1.1 jruoho { 159 1.1 jruoho const float x = 0.0L / 0.0L; 160 1.1 jruoho 161 1.1 jruoho ATF_CHECK(isnan(x) != 0); 162 1.1 jruoho ATF_CHECK(isnan(cbrtf(x)) != 0); 163 1.1 jruoho } 164 1.1 jruoho 165 1.1 jruoho ATF_TC(cbrtf_powf); 166 1.1 jruoho ATF_TC_HEAD(cbrtf_powf, tc) 167 1.1 jruoho { 168 1.1 jruoho atf_tc_set_md_var(tc, "descr", "Test cbrtf(3) vs. powf(3)"); 169 1.1 jruoho } 170 1.1 jruoho 171 1.1 jruoho ATF_TC_BODY(cbrtf_powf, tc) 172 1.1 jruoho { 173 1.1 jruoho const float x[] = { 0.0, 0.005, 1.0, 99.0, 123.123, 9999.0 }; 174 1.4 riastrad /* Neither cbrt nor pow is required to be correctly rounded. */ 175 1.4 riastrad const float eps = 2*FLT_EPSILON; 176 1.1 jruoho size_t i; 177 1.1 jruoho 178 1.1 jruoho for (i = 0; i < __arraycount(x); i++) { 179 1.4 riastrad float x_cbrt = cbrtf(x[i]); 180 1.4 riastrad float x_pow13 = powf(x[i], 1.0 / 3.0); 181 1.4 riastrad bool ok; 182 1.4 riastrad 183 1.4 riastrad if (x[i] == 0) { 184 1.4 riastrad ok = (x_cbrt == x_pow13); 185 1.4 riastrad } else { 186 1.4 riastrad ok = (fabsf((x_cbrt - x_pow13)/x_cbrt) <= eps); 187 1.4 riastrad } 188 1.4 riastrad 189 1.4 riastrad if (!ok) { 190 1.4 riastrad atf_tc_fail_nonfatal("cbrtf(%.9g) = %.9g. != " 191 1.4 riastrad "powf(%.9g, 1/3) = %.9g\n", 192 1.4 riastrad (double)x[i], (double)x_cbrt, 193 1.4 riastrad (double)x[i], (double)x_pow13); 194 1.4 riastrad } 195 1.1 jruoho } 196 1.1 jruoho } 197 1.1 jruoho 198 1.1 jruoho ATF_TC(cbrtf_inf_neg); 199 1.1 jruoho ATF_TC_HEAD(cbrtf_inf_neg, tc) 200 1.1 jruoho { 201 1.1 jruoho atf_tc_set_md_var(tc, "descr", "Test cbrtf(-Inf) == -Inf"); 202 1.1 jruoho } 203 1.1 jruoho 204 1.1 jruoho ATF_TC_BODY(cbrtf_inf_neg, tc) 205 1.1 jruoho { 206 1.1 jruoho const float x = -1.0L / 0.0L; 207 1.1 jruoho float y = cbrtf(x); 208 1.1 jruoho 209 1.1 jruoho ATF_CHECK(isinf(y) != 0); 210 1.1 jruoho ATF_CHECK(signbit(y) != 0); 211 1.1 jruoho } 212 1.1 jruoho 213 1.1 jruoho ATF_TC(cbrtf_inf_pos); 214 1.1 jruoho ATF_TC_HEAD(cbrtf_inf_pos, tc) 215 1.1 jruoho { 216 1.1 jruoho atf_tc_set_md_var(tc, "descr", "Test cbrtf(+Inf) == +Inf"); 217 1.1 jruoho } 218 1.1 jruoho 219 1.1 jruoho ATF_TC_BODY(cbrtf_inf_pos, tc) 220 1.1 jruoho { 221 1.1 jruoho const float x = 1.0L / 0.0L; 222 1.1 jruoho float y = cbrtf(x); 223 1.1 jruoho 224 1.1 jruoho ATF_CHECK(isinf(y) != 0); 225 1.1 jruoho ATF_CHECK(signbit(y) == 0); 226 1.1 jruoho } 227 1.1 jruoho 228 1.1 jruoho ATF_TC(cbrtf_zero_neg); 229 1.1 jruoho ATF_TC_HEAD(cbrtf_zero_neg, tc) 230 1.1 jruoho { 231 1.1 jruoho atf_tc_set_md_var(tc, "descr", "Test cbrtf(-0.0) == -0.0"); 232 1.1 jruoho } 233 1.1 jruoho 234 1.1 jruoho ATF_TC_BODY(cbrtf_zero_neg, tc) 235 1.1 jruoho { 236 1.1 jruoho const float x = -0.0L; 237 1.1 jruoho float y = cbrtf(x); 238 1.1 jruoho 239 1.1 jruoho if (fabsf(y) > 0.0 || signbit(y) == 0) 240 1.1 jruoho atf_tc_fail_nonfatal("cbrtf(-0.0) != -0.0"); 241 1.1 jruoho } 242 1.1 jruoho 243 1.1 jruoho ATF_TC(cbrtf_zero_pos); 244 1.1 jruoho ATF_TC_HEAD(cbrtf_zero_pos, tc) 245 1.1 jruoho { 246 1.1 jruoho atf_tc_set_md_var(tc, "descr", "Test cbrtf(+0.0) == +0.0"); 247 1.1 jruoho } 248 1.1 jruoho 249 1.1 jruoho ATF_TC_BODY(cbrtf_zero_pos, tc) 250 1.1 jruoho { 251 1.1 jruoho const float x = 0.0L; 252 1.1 jruoho float y = cbrtf(x); 253 1.1 jruoho 254 1.1 jruoho if (fabsf(y) > 0.0 || signbit(y) != 0) 255 1.1 jruoho atf_tc_fail_nonfatal("cbrtf(+0.0) != +0.0"); 256 1.1 jruoho } 257 1.1 jruoho 258 1.2 joerg /* 259 1.2 joerg * cbrtl(3) 260 1.2 joerg */ 261 1.2 joerg ATF_TC(cbrtl_nan); 262 1.2 joerg ATF_TC_HEAD(cbrtl_nan, tc) 263 1.2 joerg { 264 1.2 joerg atf_tc_set_md_var(tc, "descr", "Test cbrtl(NaN) == NaN"); 265 1.2 joerg } 266 1.2 joerg 267 1.2 joerg ATF_TC_BODY(cbrtl_nan, tc) 268 1.2 joerg { 269 1.2 joerg const long double x = 0.0L / 0.0L; 270 1.2 joerg 271 1.2 joerg ATF_CHECK(isnan(x) != 0); 272 1.2 joerg ATF_CHECK(isnan(cbrtl(x)) != 0); 273 1.2 joerg } 274 1.2 joerg 275 1.2 joerg ATF_TC(cbrtl_powl); 276 1.2 joerg ATF_TC_HEAD(cbrtl_powl, tc) 277 1.2 joerg { 278 1.2 joerg atf_tc_set_md_var(tc, "descr", "Test cbrtl(3) vs. powl(3)"); 279 1.2 joerg } 280 1.2 joerg 281 1.2 joerg ATF_TC_BODY(cbrtl_powl, tc) 282 1.2 joerg { 283 1.2 joerg const long double x[] = { 0.0, 0.005, 1.0, 99.0, 123.123, 9999.0 }; 284 1.4 riastrad /* Neither cbrt nor pow is required to be correctly rounded. */ 285 1.4 riastrad const long double eps = 2*LDBL_EPSILON; 286 1.2 joerg size_t i; 287 1.2 joerg 288 1.2 joerg for (i = 0; i < __arraycount(x); i++) { 289 1.4 riastrad long double x_cbrt = cbrtl(x[i]); 290 1.6 christos long double x_pow13 = powl(x[i], 1.0L / 3.0L); 291 1.4 riastrad bool ok; 292 1.4 riastrad 293 1.4 riastrad if (x[i] == 0) { 294 1.4 riastrad ok = (x_cbrt == x_pow13); 295 1.4 riastrad } else { 296 1.4 riastrad ok = (fabsl((x_cbrt - x_pow13)/x_cbrt) <= eps); 297 1.4 riastrad } 298 1.4 riastrad 299 1.4 riastrad if (!ok) { 300 1.4 riastrad atf_tc_fail_nonfatal("cbrtl(%.35Lg) = %.35Lg != " 301 1.4 riastrad "powl(%.35Lg, 1/3) = %.35Lg\n", 302 1.4 riastrad x[i], x_cbrt, x[i], x_pow13); 303 1.4 riastrad } 304 1.2 joerg } 305 1.2 joerg } 306 1.2 joerg 307 1.2 joerg ATF_TC(cbrtl_inf_neg); 308 1.2 joerg ATF_TC_HEAD(cbrtl_inf_neg, tc) 309 1.2 joerg { 310 1.2 joerg atf_tc_set_md_var(tc, "descr", "Test cbrtl(-Inf) == -Inf"); 311 1.2 joerg } 312 1.2 joerg 313 1.2 joerg ATF_TC_BODY(cbrtl_inf_neg, tc) 314 1.2 joerg { 315 1.2 joerg const long double x = -1.0L / 0.0L; 316 1.2 joerg long double y = cbrtl(x); 317 1.2 joerg 318 1.2 joerg ATF_CHECK(isinf(y) != 0); 319 1.2 joerg ATF_CHECK(signbit(y) != 0); 320 1.2 joerg } 321 1.2 joerg 322 1.2 joerg ATF_TC(cbrtl_inf_pos); 323 1.2 joerg ATF_TC_HEAD(cbrtl_inf_pos, tc) 324 1.2 joerg { 325 1.2 joerg atf_tc_set_md_var(tc, "descr", "Test cbrtl(+Inf) == +Inf"); 326 1.2 joerg } 327 1.2 joerg 328 1.2 joerg ATF_TC_BODY(cbrtl_inf_pos, tc) 329 1.2 joerg { 330 1.2 joerg const long double x = 1.0L / 0.0L; 331 1.2 joerg long double y = cbrtl(x); 332 1.2 joerg 333 1.2 joerg ATF_CHECK(isinf(y) != 0); 334 1.2 joerg ATF_CHECK(signbit(y) == 0); 335 1.2 joerg } 336 1.2 joerg 337 1.2 joerg ATF_TC(cbrtl_zero_neg); 338 1.2 joerg ATF_TC_HEAD(cbrtl_zero_neg, tc) 339 1.2 joerg { 340 1.2 joerg atf_tc_set_md_var(tc, "descr", "Test cbrtl(-0.0) == -0.0"); 341 1.2 joerg } 342 1.2 joerg 343 1.2 joerg ATF_TC_BODY(cbrtl_zero_neg, tc) 344 1.2 joerg { 345 1.2 joerg const long double x = -0.0L; 346 1.2 joerg long double y = cbrtl(x); 347 1.2 joerg 348 1.2 joerg if (fabsl(y) > 0.0 || signbit(y) == 0) 349 1.2 joerg atf_tc_fail_nonfatal("cbrtl(-0.0) != -0.0"); 350 1.2 joerg } 351 1.2 joerg 352 1.2 joerg ATF_TC(cbrtl_zero_pos); 353 1.2 joerg ATF_TC_HEAD(cbrtl_zero_pos, tc) 354 1.2 joerg { 355 1.2 joerg atf_tc_set_md_var(tc, "descr", "Test cbrtl(+0.0) == +0.0"); 356 1.2 joerg } 357 1.2 joerg 358 1.2 joerg ATF_TC_BODY(cbrtl_zero_pos, tc) 359 1.2 joerg { 360 1.2 joerg const long double x = 0.0L; 361 1.2 joerg long double y = cbrtl(x); 362 1.2 joerg 363 1.2 joerg if (fabsl(y) > 0.0 || signbit(y) != 0) 364 1.2 joerg atf_tc_fail_nonfatal("cbrtl(+0.0) != +0.0"); 365 1.2 joerg } 366 1.2 joerg 367 1.1 jruoho ATF_TP_ADD_TCS(tp) 368 1.1 jruoho { 369 1.1 jruoho 370 1.1 jruoho ATF_TP_ADD_TC(tp, cbrt_nan); 371 1.1 jruoho ATF_TP_ADD_TC(tp, cbrt_pow); 372 1.1 jruoho ATF_TP_ADD_TC(tp, cbrt_inf_neg); 373 1.1 jruoho ATF_TP_ADD_TC(tp, cbrt_inf_pos); 374 1.1 jruoho ATF_TP_ADD_TC(tp, cbrt_zero_neg); 375 1.1 jruoho ATF_TP_ADD_TC(tp, cbrt_zero_pos); 376 1.1 jruoho 377 1.1 jruoho ATF_TP_ADD_TC(tp, cbrtf_nan); 378 1.1 jruoho ATF_TP_ADD_TC(tp, cbrtf_powf); 379 1.1 jruoho ATF_TP_ADD_TC(tp, cbrtf_inf_neg); 380 1.1 jruoho ATF_TP_ADD_TC(tp, cbrtf_inf_pos); 381 1.1 jruoho ATF_TP_ADD_TC(tp, cbrtf_zero_neg); 382 1.1 jruoho ATF_TP_ADD_TC(tp, cbrtf_zero_pos); 383 1.1 jruoho 384 1.2 joerg ATF_TP_ADD_TC(tp, cbrtl_nan); 385 1.2 joerg ATF_TP_ADD_TC(tp, cbrtl_powl); 386 1.2 joerg ATF_TP_ADD_TC(tp, cbrtl_inf_neg); 387 1.2 joerg ATF_TP_ADD_TC(tp, cbrtl_inf_pos); 388 1.2 joerg ATF_TP_ADD_TC(tp, cbrtl_zero_neg); 389 1.2 joerg ATF_TP_ADD_TC(tp, cbrtl_zero_pos); 390 1.2 joerg 391 1.1 jruoho return atf_no_error(); 392 1.1 jruoho } 393