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