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