Home | History | Annotate | Line # | Download | only in src
      1 /* @(#)k_standard.c 5.1 93/09/24 */
      2 /*
      3  * ====================================================
      4  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
      5  *
      6  * Developed at SunPro, a Sun Microsystems, Inc. business.
      7  * Permission to use, copy, modify, and distribute this
      8  * software is freely granted, provided that this notice
      9  * is preserved.
     10  * ====================================================
     11  */
     12 
     13 #include <sys/cdefs.h>
     14 #if defined(LIBM_SCCS) && !defined(lint)
     15 __RCSID("$NetBSD: k_standard.c,v 1.23 2021/04/12 09:15:52 mrg Exp $");
     16 #endif
     17 
     18 #include "math.h"
     19 #include "math_private.h"
     20 #include <errno.h>
     21 
     22 #ifndef _USE_WRITE
     23 #include <stdio.h>			/* fputs(), stderr */
     24 #define	WRITE2(u,v)	fputs(u, stderr)
     25 #else	/* !defined(_USE_WRITE) */
     26 #include <unistd.h>			/* write */
     27 #define	WRITE2(u,v)	write(2, u, v)
     28 #undef fflush
     29 #endif	/* !defined(_USE_WRITE) */
     30 
     31 static const double zero = 0.0;	/* used as const */
     32 
     33 /*
     34  * Standard conformance (non-IEEE) on exception cases.
     35  * Mapping:
     36  *	1 -- acos(|x|>1)
     37  *	2 -- asin(|x|>1)
     38  *	3 -- atan2(+-0,+-0)
     39  *	4 -- hypot overflow
     40  *	5 -- cosh overflow
     41  *	6 -- exp overflow
     42  *	7 -- exp underflow
     43  *	8 -- y0(0)
     44  *	9 -- y0(-ve)
     45  *	10-- y1(0)
     46  *	11-- y1(-ve)
     47  *	12-- yn(0)
     48  *	13-- yn(-ve)
     49  *	14-- lgamma(finite) overflow
     50  *	15-- lgamma(-integer)
     51  *	16-- log(0)
     52  *	17-- log(x<0)
     53  *	18-- log10(0)
     54  *	19-- log10(x<0)
     55  *	20-- pow(0.0,0.0)
     56  *	21-- pow(x,y) overflow
     57  *	22-- pow(x,y) underflow
     58  *	23-- pow(0,negative)
     59  *	24-- pow(neg,non-integral)
     60  *	25-- sinh(finite) overflow
     61  *	26-- sqrt(negative)
     62  *      27-- fmod(x,0)
     63  *      28-- remainder(x,0)
     64  *	29-- acosh(x<1)
     65  *	30-- atanh(|x|>1)
     66  *	31-- atanh(|x|=1)
     67  *	32-- scalb overflow
     68  *	33-- scalb underflow
     69  *	34-- j0(|x|>X_TLOSS)
     70  *	35-- y0(x>X_TLOSS)
     71  *	36-- j1(|x|>X_TLOSS)
     72  *	37-- y1(x>X_TLOSS)
     73  *	38-- jn(|x|>X_TLOSS, n)
     74  *	39-- yn(x>X_TLOSS, n)
     75  *	40-- gamma(finite) overflow
     76  *	41-- gamma(-integer)
     77  *	42-- pow(NaN,0.0)
     78  *	48-- log2(0)
     79  *	49-- log2(x<0)
     80  */
     81 
     82 
     83 double
     84 __kernel_standard(double x, double y, int type)
     85 {
     86 	struct exception exc;
     87 #ifndef HUGE_VAL	/* this is the only routine that uses HUGE_VAL */
     88 #define HUGE_VAL inf
     89 	double inf = 0.0;
     90 
     91 	SET_HIGH_WORD(inf,0x7ff00000);	/* set inf to infinite */
     92 #endif
     93 
     94 #ifdef _USE_WRITE
     95 	(void) fflush(stdout);
     96 #endif
     97 	exc.arg1 = x;
     98 	exc.arg2 = y;
     99 	switch(type) {
    100 	    case 1:
    101 	    case 101:
    102 		/* acos(|x|>1) */
    103 		exc.type = DOMAIN;
    104 		exc.name = type < 100 ? "acos" : "acosf";
    105 		exc.retval = zero;
    106 		if (_LIB_VERSION == _POSIX_) {
    107 		  exc.retval = zero/zero;
    108 		  errno = EDOM;
    109 		} else if (!matherr(&exc)) {
    110 		  if(_LIB_VERSION == _SVID_) {
    111 		    (void) WRITE2("acos: DOMAIN error\n", 19);
    112 		  }
    113 		  errno = EDOM;
    114 		}
    115 		break;
    116 	    case 2:
    117 	    case 102:
    118 		/* asin(|x|>1) */
    119 		exc.type = DOMAIN;
    120 		exc.name = type < 100 ? "asin" : "asinf";
    121 		exc.retval = zero;
    122 		if(_LIB_VERSION == _POSIX_) {
    123 		  exc.retval = zero/zero;
    124 		  errno = EDOM;
    125 		} else if (!matherr(&exc)) {
    126 		  if(_LIB_VERSION == _SVID_) {
    127 		    	(void) WRITE2("asin: DOMAIN error\n", 19);
    128 		  }
    129 		  errno = EDOM;
    130 		}
    131 		break;
    132 	    case 3:
    133 	    case 103:
    134 		/* atan2(+-0,+-0) */
    135 		exc.arg1 = y;
    136 		exc.arg2 = x;
    137 		exc.type = DOMAIN;
    138 		exc.name = type < 100 ? "atan2" : "atan2f";
    139 		exc.retval = zero;
    140 		if(_LIB_VERSION == _POSIX_) {
    141 		  exc.retval = copysign(signbit(y) ? M_PI : zero, x);
    142 		} else if (!matherr(&exc)) {
    143 		  if(_LIB_VERSION == _SVID_) {
    144 			(void) WRITE2("atan2: DOMAIN error\n", 20);
    145 		      }
    146 		  errno = EDOM;
    147 		}
    148 		break;
    149 	    case 4:
    150 	    case 104:
    151 		/* hypot(finite,finite) overflow */
    152 		exc.type = OVERFLOW;
    153 		exc.name = type < 100 ? "hypot" : "hypotf";
    154 		if (_LIB_VERSION == _SVID_)
    155 		  exc.retval = HUGE;
    156 		else
    157 		  exc.retval = HUGE_VAL;
    158 		if (_LIB_VERSION == _POSIX_)
    159 		  errno = ERANGE;
    160 		else if (!matherr(&exc)) {
    161 			errno = ERANGE;
    162 		}
    163 		break;
    164 	    case 5:
    165 	    case 105:
    166 		/* cosh(finite) overflow */
    167 		exc.type = OVERFLOW;
    168 		exc.name = type < 100 ? "cosh" : "coshf";
    169 		if (_LIB_VERSION == _SVID_)
    170 		  exc.retval = HUGE;
    171 		else
    172 		  exc.retval = HUGE_VAL;
    173 		if (_LIB_VERSION == _POSIX_)
    174 		  errno = ERANGE;
    175 		else if (!matherr(&exc)) {
    176 			errno = ERANGE;
    177 		}
    178 		break;
    179 	    case 6:
    180 	    case 106:
    181 		/* exp(finite) overflow */
    182 		exc.type = OVERFLOW;
    183 		exc.name = type < 100 ? "exp" : "expf";
    184 		if (_LIB_VERSION == _SVID_)
    185 		  exc.retval = HUGE;
    186 		else
    187 		  exc.retval = HUGE_VAL;
    188 		if (_LIB_VERSION == _POSIX_)
    189 		  errno = ERANGE;
    190 		else if (!matherr(&exc)) {
    191 			errno = ERANGE;
    192 		}
    193 		break;
    194 	    case 7:
    195 	    case 107:
    196 		/* exp(finite) underflow */
    197 		exc.type = UNDERFLOW;
    198 		exc.name = type < 100 ? "exp" : "expf";
    199 		exc.retval = zero;
    200 		if (_LIB_VERSION == _POSIX_)
    201 		  errno = ERANGE;
    202 		else if (!matherr(&exc)) {
    203 			errno = ERANGE;
    204 		}
    205 		break;
    206 	    case 8:
    207 	    case 108:
    208 		/* y0(0) = -inf */
    209 		exc.type = DOMAIN;	/* should be SING for IEEE */
    210 		exc.name = type < 100 ? "y0" : "y0f";
    211 		if (_LIB_VERSION == _SVID_)
    212 		  exc.retval = -HUGE;
    213 		else
    214 		  exc.retval = -HUGE_VAL;
    215 		if (_LIB_VERSION == _POSIX_)
    216 		  errno = EDOM;
    217 		else if (!matherr(&exc)) {
    218 		  if (_LIB_VERSION == _SVID_) {
    219 			(void) WRITE2("y0: DOMAIN error\n", 17);
    220 		      }
    221 		  errno = EDOM;
    222 		}
    223 		break;
    224 	    case 9:
    225 	    case 109:
    226 		/* y0(x<0) = NaN */
    227 		exc.type = DOMAIN;
    228 		exc.name = type < 100 ? "y0" : "y0f";
    229 		if (_LIB_VERSION == _SVID_)
    230 		  exc.retval = -HUGE;
    231 		else
    232 		  exc.retval = -HUGE_VAL;
    233 		if (_LIB_VERSION == _POSIX_)
    234 		  errno = EDOM;
    235 		else if (!matherr(&exc)) {
    236 		  if (_LIB_VERSION == _SVID_) {
    237 			(void) WRITE2("y0: DOMAIN error\n", 17);
    238 		      }
    239 		  errno = EDOM;
    240 		}
    241 		break;
    242 	    case 10:
    243 	    case 110:
    244 		/* y1(0) = -inf */
    245 		exc.type = DOMAIN;	/* should be SING for IEEE */
    246 		exc.name = type < 100 ? "y1" : "y1f";
    247 		if (_LIB_VERSION == _SVID_)
    248 		  exc.retval = -HUGE;
    249 		else
    250 		  exc.retval = -HUGE_VAL;
    251 		if (_LIB_VERSION == _POSIX_)
    252 		  errno = EDOM;
    253 		else if (!matherr(&exc)) {
    254 		  if (_LIB_VERSION == _SVID_) {
    255 			(void) WRITE2("y1: DOMAIN error\n", 17);
    256 		      }
    257 		  errno = EDOM;
    258 		}
    259 		break;
    260 	    case 11:
    261 	    case 111:
    262 		/* y1(x<0) = NaN */
    263 		exc.type = DOMAIN;
    264 		exc.name = type < 100 ? "y1" : "y1f";
    265 		if (_LIB_VERSION == _SVID_)
    266 		  exc.retval = -HUGE;
    267 		else
    268 		  exc.retval = -HUGE_VAL;
    269 		if (_LIB_VERSION == _POSIX_)
    270 		  errno = EDOM;
    271 		else if (!matherr(&exc)) {
    272 		  if (_LIB_VERSION == _SVID_) {
    273 			(void) WRITE2("y1: DOMAIN error\n", 17);
    274 		      }
    275 		  errno = EDOM;
    276 		}
    277 		break;
    278 	    case 12:
    279 	    case 112:
    280 		/* yn(n,0) = -inf */
    281 		exc.type = DOMAIN;	/* should be SING for IEEE */
    282 		exc.name = type < 100 ? "yn" : "ynf";
    283 		if (_LIB_VERSION == _SVID_)
    284 		  exc.retval = -HUGE;
    285 		else
    286 		  exc.retval = -HUGE_VAL;
    287 		if (_LIB_VERSION == _POSIX_)
    288 		  errno = EDOM;
    289 		else if (!matherr(&exc)) {
    290 		  if (_LIB_VERSION == _SVID_) {
    291 			(void) WRITE2("yn: DOMAIN error\n", 17);
    292 		      }
    293 		  errno = EDOM;
    294 		}
    295 		break;
    296 	    case 13:
    297 	    case 113:
    298 		/* yn(x<0) = NaN */
    299 		exc.type = DOMAIN;
    300 		exc.name = type < 100 ? "yn" : "ynf";
    301 		if (_LIB_VERSION == _SVID_)
    302 		  exc.retval = -HUGE;
    303 		else
    304 		  exc.retval = -HUGE_VAL;
    305 		if (_LIB_VERSION == _POSIX_)
    306 		  errno = EDOM;
    307 		else if (!matherr(&exc)) {
    308 		  if (_LIB_VERSION == _SVID_) {
    309 			(void) WRITE2("yn: DOMAIN error\n", 17);
    310 		      }
    311 		  errno = EDOM;
    312 		}
    313 		break;
    314 	    case 14:
    315 	    case 114:
    316 		/* lgamma(finite) overflow */
    317 		exc.type = OVERFLOW;
    318 		exc.name = type < 100 ? "lgamma" : "lgammaf";
    319                 if (_LIB_VERSION == _SVID_)
    320                   exc.retval = HUGE;
    321                 else
    322                   exc.retval = HUGE_VAL;
    323                 if (_LIB_VERSION == _POSIX_)
    324 			errno = ERANGE;
    325                 else if (!matherr(&exc)) {
    326                         errno = ERANGE;
    327 		}
    328 		break;
    329 	    case 15:
    330 	    case 115:
    331 		/* lgamma(-integer) or lgamma(0) */
    332 		exc.type = SING;
    333 		exc.name = type < 100 ? "lgamma" : "lgammaf";
    334                 if (_LIB_VERSION == _SVID_)
    335                   exc.retval = HUGE;
    336                 else
    337                   exc.retval = HUGE_VAL;
    338 		if (_LIB_VERSION == _POSIX_)
    339 		  errno = EDOM;
    340 		else if (!matherr(&exc)) {
    341 		  if (_LIB_VERSION == _SVID_) {
    342 			(void) WRITE2("lgamma: SING error\n", 19);
    343 		      }
    344 		  errno = EDOM;
    345 		}
    346 		break;
    347 	    case 16:
    348 	    case 116:
    349 		/* log(0) */
    350 		exc.type = SING;
    351 		exc.name = type < 100 ? "log" : "logf";
    352 		if (_LIB_VERSION == _SVID_)
    353 		  exc.retval = -HUGE;
    354 		else
    355 		  exc.retval = -HUGE_VAL;
    356 		if (_LIB_VERSION == _POSIX_)
    357 		  errno = ERANGE;
    358 		else if (!matherr(&exc)) {
    359 		  if (_LIB_VERSION == _SVID_) {
    360 			(void) WRITE2("log: SING error\n", 16);
    361 		      }
    362 		  errno = EDOM;
    363 		}
    364 		break;
    365 	    case 17:
    366 	    case 117:
    367 		/* log(x<0) */
    368 		exc.type = DOMAIN;
    369 		exc.name = type < 100 ? "log" : "logf";
    370 		if (_LIB_VERSION == _SVID_)
    371 		  exc.retval = -HUGE;
    372 		else
    373 		  exc.retval = zero/zero;
    374 		if (_LIB_VERSION == _POSIX_)
    375 		  errno = EDOM;
    376 		else if (!matherr(&exc)) {
    377 		  if (_LIB_VERSION == _SVID_) {
    378 			(void) WRITE2("log: DOMAIN error\n", 18);
    379 		      }
    380 		  errno = EDOM;
    381 		}
    382 		break;
    383 	    case 18:
    384 	    case 118:
    385 		/* log10(0) */
    386 		exc.type = SING;
    387 		exc.name = type < 100 ? "log10" : "log10f";
    388 		if (_LIB_VERSION == _SVID_)
    389 		  exc.retval = -HUGE;
    390 		else
    391 		  exc.retval = -HUGE_VAL;
    392 		if (_LIB_VERSION == _POSIX_)
    393 		  errno = ERANGE;
    394 		else if (!matherr(&exc)) {
    395 		  if (_LIB_VERSION == _SVID_) {
    396 			(void) WRITE2("log10: SING error\n", 18);
    397 		      }
    398 		  errno = EDOM;
    399 		}
    400 		break;
    401 	    case 19:
    402 	    case 119:
    403 		/* log10(x<0) */
    404 		exc.type = DOMAIN;
    405 		exc.name = type < 100 ? "log10" : "log10f";
    406 		if (_LIB_VERSION == _SVID_)
    407 		  exc.retval = -HUGE;
    408 		else
    409 		  exc.retval = zero/zero;
    410 		if (_LIB_VERSION == _POSIX_)
    411 		  errno = EDOM;
    412 		else if (!matherr(&exc)) {
    413 		  if (_LIB_VERSION == _SVID_) {
    414 			(void) WRITE2("log10: DOMAIN error\n", 20);
    415 		      }
    416 		  errno = EDOM;
    417 		}
    418 		break;
    419 	    case 20:
    420 	    case 120:
    421 		/* pow(0.0,0.0) */
    422 		/* error only if _LIB_VERSION == _SVID_ */
    423 		exc.type = DOMAIN;
    424 		exc.name = type < 100 ? "pow" : "powf";
    425 		exc.retval = zero;
    426 		if (_LIB_VERSION != _SVID_) exc.retval = 1.0;
    427 		else if (!matherr(&exc)) {
    428 			(void) WRITE2("pow(0,0): DOMAIN error\n", 23);
    429 			errno = EDOM;
    430 		}
    431 		break;
    432 	    case 21:
    433 	    case 121:
    434 		/* pow(x,y) overflow */
    435 		exc.type = OVERFLOW;
    436 		exc.name = type < 100 ? "pow" : "powf";
    437 		if (_LIB_VERSION == _SVID_) {
    438 		  exc.retval = HUGE;
    439 		  y *= 0.5;
    440 		  if(x<zero&&rint(y)!=y) exc.retval = -HUGE;
    441 		} else {
    442 		  exc.retval = HUGE_VAL;
    443 		  y *= 0.5;
    444 		  if(x<zero&&rint(y)!=y) exc.retval = -HUGE_VAL;
    445 		}
    446 		if (_LIB_VERSION == _POSIX_)
    447 		  errno = ERANGE;
    448 		else if (!matherr(&exc)) {
    449 			errno = ERANGE;
    450 		}
    451 		break;
    452 	    case 22:
    453 	    case 122:
    454 		/* pow(x,y) underflow */
    455 		exc.type = UNDERFLOW;
    456 		exc.name = type < 100 ? "pow" : "powf";
    457 		exc.retval =  zero;
    458 		if (_LIB_VERSION == _POSIX_)
    459 		  errno = ERANGE;
    460 		else if (!matherr(&exc)) {
    461 			errno = ERANGE;
    462 		}
    463 		break;
    464 	    case 23:
    465 	    case 123:
    466 		/* 0**neg */
    467 		exc.type = DOMAIN;
    468 		exc.name = type < 100 ? "pow" : "powf";
    469 		if (_LIB_VERSION == _SVID_)
    470 		  exc.retval = zero;
    471 		else {
    472 		  exc.retval = HUGE_VAL;
    473 		  y *= 0.5;
    474 		  if(signbit(x)&&rint(y)!=y) exc.retval = -HUGE_VAL;
    475 		}
    476 		if (_LIB_VERSION == _POSIX_)
    477 		  errno = EDOM;
    478 		else if (!matherr(&exc)) {
    479 		  if (_LIB_VERSION == _SVID_) {
    480 			(void) WRITE2("pow(0,neg): DOMAIN error\n", 25);
    481 		      }
    482 		  errno = EDOM;
    483 		}
    484 		break;
    485 	    case 24:
    486 	    case 124:
    487 		/* neg**non-integral */
    488 		exc.type = DOMAIN;
    489 		exc.name = type < 100 ? "pow" : "powf";
    490 		if (_LIB_VERSION == _SVID_)
    491 		    exc.retval = zero;
    492 		else
    493 		    exc.retval = zero/zero;	/* X/Open allow NaN */
    494 		if (_LIB_VERSION == _POSIX_)
    495 		   errno = EDOM;
    496 		else if (!matherr(&exc)) {
    497 		  if (_LIB_VERSION == _SVID_) {
    498 			(void) WRITE2("neg**non-integral: DOMAIN error\n", 32);
    499 		      }
    500 		  errno = EDOM;
    501 		}
    502 		break;
    503 	    case 25:
    504 	    case 125:
    505 		/* sinh(finite) overflow */
    506 		exc.type = OVERFLOW;
    507 		exc.name = type < 100 ? "sinh" : "sinhf";
    508 		if (_LIB_VERSION == _SVID_)
    509 		  exc.retval = ( (x>zero) ? HUGE : -HUGE);
    510 		else
    511 		  exc.retval = ( (x>zero) ? HUGE_VAL : -HUGE_VAL);
    512 		if (_LIB_VERSION == _POSIX_)
    513 		  errno = ERANGE;
    514 		else if (!matherr(&exc)) {
    515 			errno = ERANGE;
    516 		}
    517 		break;
    518 	    case 26:
    519 	    case 126:
    520 	    case 226:
    521 		/* sqrt(x<0) */
    522 		exc.type = DOMAIN;
    523 		if (type == 26)
    524 			exc.name = "sqrt";
    525 		else if (type == 126)
    526 			exc.name = "sqrtf";
    527 		else
    528 			exc.name = "sqrtl";
    529 		if (_LIB_VERSION == _SVID_)
    530 		  exc.retval = zero;
    531 		else
    532 		  exc.retval = zero/zero;
    533 		if (_LIB_VERSION == _POSIX_)
    534 		  errno = EDOM;
    535 		else if (!matherr(&exc)) {
    536 		  if (_LIB_VERSION == _SVID_) {
    537 			(void) WRITE2("sqrt: DOMAIN error\n", 19);
    538 		      }
    539 		  errno = EDOM;
    540 		}
    541 		break;
    542             case 27:
    543 	    case 127:
    544 	    case 227:
    545                 /* fmod(x,0) */
    546                 exc.type = DOMAIN;
    547 		if (type == 27)
    548 			exc.name = "fmod";
    549 		else if (type == 127)
    550 			exc.name = "fmodf";
    551 		else
    552 			exc.name = "fmodl";
    553                 if (_LIB_VERSION == _SVID_)
    554                     exc.retval = x;
    555 		else
    556 		    exc.retval = zero/zero;
    557                 if (_LIB_VERSION == _POSIX_)
    558                   errno = EDOM;
    559                 else if (!matherr(&exc)) {
    560                   if (_LIB_VERSION == _SVID_) {
    561                     (void) WRITE2("fmod:  DOMAIN error\n", 20);
    562                   }
    563                   errno = EDOM;
    564                 }
    565                 break;
    566             case 28:
    567 	    case 128:
    568                 /* remainder(x,0) */
    569                 exc.type = DOMAIN;
    570                 exc.name = type < 100 ? "remainder" : "remainderf";
    571                 exc.retval = zero/zero;
    572                 if (_LIB_VERSION == _POSIX_)
    573                   errno = EDOM;
    574                 else if (!matherr(&exc)) {
    575                   if (_LIB_VERSION == _SVID_) {
    576                     (void) WRITE2("remainder: DOMAIN error\n", 24);
    577                   }
    578                   errno = EDOM;
    579                 }
    580                 break;
    581             case 29:
    582 	    case 129:
    583                 /* acosh(x<1) */
    584                 exc.type = DOMAIN;
    585                 exc.name = type < 100 ? "acosh" : "acoshf";
    586                 exc.retval = zero/zero;
    587                 if (_LIB_VERSION == _POSIX_)
    588                   errno = EDOM;
    589                 else if (!matherr(&exc)) {
    590                   if (_LIB_VERSION == _SVID_) {
    591                     (void) WRITE2("acosh: DOMAIN error\n", 20);
    592                   }
    593                   errno = EDOM;
    594                 }
    595                 break;
    596             case 30:
    597 	    case 130:
    598                 /* atanh(|x|>1) */
    599                 exc.type = DOMAIN;
    600                 exc.name = type < 100 ? "atanh" : "atanhf";
    601                 exc.retval = zero/zero;
    602                 if (_LIB_VERSION == _POSIX_)
    603                   errno = EDOM;
    604                 else if (!matherr(&exc)) {
    605                   if (_LIB_VERSION == _SVID_) {
    606                     (void) WRITE2("atanh: DOMAIN error\n", 20);
    607                   }
    608                   errno = EDOM;
    609                 }
    610                 break;
    611             case 31:
    612 	    case 131:
    613                 /* atanh(|x|=1) */
    614                 exc.type = SING;
    615                 exc.name = type < 100 ? "atanh" : "atanhf";
    616 		exc.retval = x/zero;	/* sign(x)*inf */
    617                 if (_LIB_VERSION == _POSIX_)
    618                   errno = EDOM;
    619                 else if (!matherr(&exc)) {
    620                   if (_LIB_VERSION == _SVID_) {
    621                     (void) WRITE2("atanh: SING error\n", 18);
    622                   }
    623                   errno = EDOM;
    624                 }
    625                 break;
    626 	    case 32:
    627 	    case 132:
    628 		/* scalb overflow; SVID also returns +-HUGE_VAL */
    629 		exc.type = OVERFLOW;
    630 		exc.name = type < 100 ? "scalb" : "scalbf";
    631 		exc.retval = x > zero ? HUGE_VAL : -HUGE_VAL;
    632 		if (_LIB_VERSION == _POSIX_)
    633 		  errno = ERANGE;
    634 		else if (!matherr(&exc)) {
    635 			errno = ERANGE;
    636 		}
    637 		break;
    638 	    case 33:
    639 	    case 133:
    640 		/* scalb underflow */
    641 		exc.type = UNDERFLOW;
    642 		exc.name = type < 100 ? "scalb" : "scalbf";
    643 		exc.retval = copysign(zero,x);
    644 		if (_LIB_VERSION == _POSIX_)
    645 		  errno = ERANGE;
    646 		else if (!matherr(&exc)) {
    647 			errno = ERANGE;
    648 		}
    649 		break;
    650 	    case 34:
    651 	    case 134:
    652 		/* j0(|x|>X_TLOSS) */
    653                 exc.type = TLOSS;
    654                 exc.name = type < 100 ? "j0" : "j0f";
    655                 exc.retval = zero;
    656                 if (_LIB_VERSION == _POSIX_)
    657                         errno = ERANGE;
    658                 else if (!matherr(&exc)) {
    659                         if (_LIB_VERSION == _SVID_) {
    660                                 (void) WRITE2(exc.name, 2);
    661                                 (void) WRITE2(": TLOSS error\n", 14);
    662                         }
    663                         errno = ERANGE;
    664                 }
    665 		break;
    666 	    case 35:
    667 	    case 135:
    668 		/* y0(x>X_TLOSS) */
    669                 exc.type = TLOSS;
    670                 exc.name = type < 100 ? "y0" : "y0f";
    671                 exc.retval = zero;
    672                 if (_LIB_VERSION == _POSIX_)
    673                         errno = ERANGE;
    674                 else if (!matherr(&exc)) {
    675                         if (_LIB_VERSION == _SVID_) {
    676                                 (void) WRITE2(exc.name, 2);
    677                                 (void) WRITE2(": TLOSS error\n", 14);
    678                         }
    679                         errno = ERANGE;
    680                 }
    681 		break;
    682 	    case 36:
    683 	    case 136:
    684 		/* j1(|x|>X_TLOSS) */
    685                 exc.type = TLOSS;
    686                 exc.name = type < 100 ? "j1" : "j1f";
    687                 exc.retval = zero;
    688                 if (_LIB_VERSION == _POSIX_)
    689                         errno = ERANGE;
    690                 else if (!matherr(&exc)) {
    691                         if (_LIB_VERSION == _SVID_) {
    692                                 (void) WRITE2(exc.name, 2);
    693                                 (void) WRITE2(": TLOSS error\n", 14);
    694                         }
    695                         errno = ERANGE;
    696                 }
    697 		break;
    698 	    case 37:
    699 	    case 137:
    700 		/* y1(x>X_TLOSS) */
    701                 exc.type = TLOSS;
    702                 exc.name = type < 100 ? "y1" : "y1f";
    703                 exc.retval = zero;
    704                 if (_LIB_VERSION == _POSIX_)
    705                         errno = ERANGE;
    706                 else if (!matherr(&exc)) {
    707                         if (_LIB_VERSION == _SVID_) {
    708                                 (void) WRITE2(exc.name, 2);
    709                                 (void) WRITE2(": TLOSS error\n", 14);
    710                         }
    711                         errno = ERANGE;
    712                 }
    713 		break;
    714 	    case 38:
    715 	    case 138:
    716 		/* jn(|x|>X_TLOSS) */
    717                 exc.type = TLOSS;
    718                 exc.name = type < 100 ? "jn" : "jnf";
    719                 exc.retval = zero;
    720                 if (_LIB_VERSION == _POSIX_)
    721                         errno = ERANGE;
    722                 else if (!matherr(&exc)) {
    723                         if (_LIB_VERSION == _SVID_) {
    724                                 (void) WRITE2(exc.name, 2);
    725                                 (void) WRITE2(": TLOSS error\n", 14);
    726                         }
    727                         errno = ERANGE;
    728                 }
    729 		break;
    730 	    case 39:
    731 	    case 139:
    732 		/* yn(x>X_TLOSS) */
    733                 exc.type = TLOSS;
    734                 exc.name = type < 100 ? "yn" : "ynf";
    735                 exc.retval = zero;
    736                 if (_LIB_VERSION == _POSIX_)
    737                         errno = ERANGE;
    738                 else if (!matherr(&exc)) {
    739                         if (_LIB_VERSION == _SVID_) {
    740                                 (void) WRITE2(exc.name, 2);
    741                                 (void) WRITE2(": TLOSS error\n", 14);
    742                         }
    743                         errno = ERANGE;
    744                 }
    745 		break;
    746 	    case 40:
    747 	    case 140:
    748 		/* gamma(finite) overflow */
    749 		exc.type = OVERFLOW;
    750 		exc.name = type < 100 ? "gamma" : "gammaf";
    751                 if (_LIB_VERSION == _SVID_)
    752                   exc.retval = HUGE;
    753                 else
    754                   exc.retval = HUGE_VAL;
    755                 if (_LIB_VERSION == _POSIX_)
    756 		  errno = ERANGE;
    757                 else if (!matherr(&exc)) {
    758                   errno = ERANGE;
    759                 }
    760 		break;
    761 	    case 41:
    762 	    case 141:
    763 		/* gamma(-integer) or gamma(0) */
    764 		exc.type = SING;
    765 		exc.name = type < 100 ? "gamma" : "gammaf";
    766                 if (_LIB_VERSION == _SVID_)
    767                   exc.retval = HUGE;
    768                 else
    769                   exc.retval = HUGE_VAL;
    770 		if (_LIB_VERSION == _POSIX_)
    771 		  errno = EDOM;
    772 		else if (!matherr(&exc)) {
    773 		  if (_LIB_VERSION == _SVID_) {
    774 			(void) WRITE2("gamma: SING error\n", 18);
    775 		      }
    776 		  errno = EDOM;
    777 		}
    778 		break;
    779 	    case 42:
    780 	    case 142:
    781 		/* pow(NaN,0.0) */
    782 		/* error only if _LIB_VERSION == _SVID_ & _XOPEN_ */
    783 		exc.type = DOMAIN;
    784 		exc.name = type < 100 ? "pow" : "powf";
    785 		exc.retval = x;
    786 		if (_LIB_VERSION == _IEEE_ ||
    787 		    _LIB_VERSION == _POSIX_) exc.retval = 1.0;
    788 		else if (!matherr(&exc)) {
    789 			errno = EDOM;
    790 		}
    791 		break;
    792 	    case 48:
    793 	    case 148:
    794 		/* log2(0) */
    795 		exc.type = SING;
    796 		exc.name = type < 100 ? "log2" : "log2f";
    797 		if (_LIB_VERSION == _SVID_)
    798 		  exc.retval = -HUGE;
    799 		else
    800 		  exc.retval = -HUGE_VAL;
    801 		if (_LIB_VERSION == _POSIX_)
    802 		  errno = ERANGE;
    803 		else if (!matherr(&exc)) {
    804 		  if (_LIB_VERSION == _SVID_) {
    805 			(void) WRITE2("log2: SING error\n", 18);
    806 		      }
    807 		  errno = EDOM;
    808 		}
    809 		break;
    810 	    case 49:
    811 	    case 149:
    812 		/* log2(x<0) */
    813 		exc.type = DOMAIN;
    814 		exc.name = type < 100 ? "log2" : "log2f";
    815 		if (_LIB_VERSION == _SVID_)
    816 		  exc.retval = -HUGE;
    817 		else
    818 		  exc.retval = zero/zero;
    819 		if (_LIB_VERSION == _POSIX_)
    820 		  errno = EDOM;
    821 		else if (!matherr(&exc)) {
    822 		  if (_LIB_VERSION == _SVID_) {
    823 			(void) WRITE2("log2: DOMAIN error\n", 20);
    824 		      }
    825 		  errno = EDOM;
    826 		}
    827 		break;
    828 	    default:
    829 		if (_LIB_VERSION == _SVID_)
    830 		  exc.retval = -HUGE;
    831 		else
    832 		  exc.retval = -HUGE_VAL;
    833 		errno = EDOM;
    834 		break;
    835 	}
    836 	return exc.retval;
    837 }
    838