xref: /netbsd-src/lib/libm/src/k_standard.c (revision d9158b13b5dfe46201430699a3f7a235ecf28df3)
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 #ifndef lint
14 static char rcsid[] = "$Id: k_standard.c,v 1.3 1994/02/18 02:26:04 jtc Exp $";
15 #endif
16 
17 #include <math.h>
18 #include <errno.h>
19 
20 #ifndef _USE_WRITE
21 #include <stdio.h>			/* fputs(), stderr */
22 #define	WRITE2(u,v)	fputs(u, stderr)
23 #else	/* !defined(_USE_WRITE) */
24 #include <unistd.h>			/* write */
25 #define	WRITE2(u,v)	write(2, u, v)
26 #undef fflush
27 #endif	/* !defined(_USE_WRITE) */
28 
29 static double zero = 0.0;	/* used as const */
30 
31 /*
32  * Standard conformance (non-IEEE) on exception cases.
33  * Mapping:
34  *	1 -- acos(|x|>1)
35  *	2 -- asin(|x|>1)
36  *	3 -- atan2(+-0,+-0)
37  *	4 -- hypot overflow
38  *	5 -- cosh overflow
39  *	6 -- exp overflow
40  *	7 -- exp underflow
41  *	8 -- y0(0)
42  *	9 -- y0(-ve)
43  *	10-- y1(0)
44  *	11-- y1(-ve)
45  *	12-- yn(0)
46  *	13-- yn(-ve)
47  *	14-- lgamma(finite) overflow
48  *	15-- lgamma(-integer)
49  *	16-- log(0)
50  *	17-- log(x<0)
51  *	18-- log10(0)
52  *	19-- log10(x<0)
53  *	20-- pow(0.0,0.0)
54  *	21-- pow(x,y) overflow
55  *	22-- pow(x,y) underflow
56  *	23-- pow(0,negative)
57  *	24-- pow(neg,non-integral)
58  *	25-- sinh(finite) overflow
59  *	26-- sqrt(negative)
60  *      27-- fmod(x,0)
61  *      28-- remainder(x,0)
62  *	29-- acosh(x<1)
63  *	30-- atanh(|x|>1)
64  *	31-- atanh(|x|=1)
65  *	32-- scalb overflow
66  *	33-- scalb underflow
67  *	34-- j0(|x|>X_TLOSS)
68  *	35-- y0(x>X_TLOSS)
69  *	36-- j1(|x|>X_TLOSS)
70  *	37-- y1(x>X_TLOSS)
71  *	38-- jn(|x|>X_TLOSS, n)
72  *	39-- yn(x>X_TLOSS, n)
73  *	40-- gamma(finite) overflow
74  *	41-- gamma(-integer)
75  *	42-- pow(NaN,0.0)
76  */
77 
78 
79 #ifdef __STDC__
80 	double __kernel_standard(double x, double y, int type)
81 #else
82 	double __kernel_standard(x,y,type)
83 	double x,y; int type;
84 #endif
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 one = 1.0, inf = 0.0;
90 	int i0;
91 
92 	i0 = ((*(int*)&one)>>29)^1;
93 	*(i0+(int*)&inf) = 0x7ff00000;	/* set inf to infinite */
94 #endif
95 
96 #ifdef _USE_WRITE
97 	(void) fflush(stdout);
98 #endif
99 	exc.arg1 = x;
100 	exc.arg2 = y;
101 	switch(type) {
102 	    case 1:
103 		/* acos(|x|>1) */
104 		exc.type = DOMAIN;
105 		exc.name = "acos";
106 		exc.retval = zero;
107 		if (_LIB_VERSION == _POSIX_)
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 		/* asin(|x|>1) */
118 		exc.type = DOMAIN;
119 		exc.name = "asin";
120 		exc.retval = zero;
121 		if(_LIB_VERSION == _POSIX_)
122 		  errno = EDOM;
123 		else if (!matherr(&exc)) {
124 		  if(_LIB_VERSION == _SVID_) {
125 		    	(void) WRITE2("asin: DOMAIN error\n", 19);
126 		  }
127 		  errno = EDOM;
128 		}
129 		break;
130 	    case 3:
131 		/* atan2(+-0,+-0) */
132 		exc.arg1 = y;
133 		exc.arg2 = x;
134 		exc.type = DOMAIN;
135 		exc.name = "atan2";
136 		exc.retval = zero;
137 		if(_LIB_VERSION == _POSIX_)
138 		  errno = EDOM;
139 		else if (!matherr(&exc)) {
140 		  if(_LIB_VERSION == _SVID_) {
141 			(void) WRITE2("atan2: DOMAIN error\n", 20);
142 		      }
143 		  errno = EDOM;
144 		}
145 		break;
146 	    case 4:
147 		/* hypot(finite,finite) overflow */
148 		exc.type = OVERFLOW;
149 		exc.name = "hypot";
150 		if (_LIB_VERSION == _SVID_)
151 		  exc.retval = HUGE;
152 		else
153 		  exc.retval = HUGE_VAL;
154 		if (_LIB_VERSION == _POSIX_)
155 		  errno = ERANGE;
156 		else if (!matherr(&exc)) {
157 			errno = ERANGE;
158 		}
159 		break;
160 	    case 5:
161 		/* cosh(finite) overflow */
162 		exc.type = OVERFLOW;
163 		exc.name = "cosh";
164 		if (_LIB_VERSION == _SVID_)
165 		  exc.retval = HUGE;
166 		else
167 		  exc.retval = HUGE_VAL;
168 		if (_LIB_VERSION == _POSIX_)
169 		  errno = ERANGE;
170 		else if (!matherr(&exc)) {
171 			errno = ERANGE;
172 		}
173 		break;
174 	    case 6:
175 		/* exp(finite) overflow */
176 		exc.type = OVERFLOW;
177 		exc.name = "exp";
178 		if (_LIB_VERSION == _SVID_)
179 		  exc.retval = HUGE;
180 		else
181 		  exc.retval = HUGE_VAL;
182 		if (_LIB_VERSION == _POSIX_)
183 		  errno = ERANGE;
184 		else if (!matherr(&exc)) {
185 			errno = ERANGE;
186 		}
187 		break;
188 	    case 7:
189 		/* exp(finite) underflow */
190 		exc.type = UNDERFLOW;
191 		exc.name = "exp";
192 		exc.retval = zero;
193 		if (_LIB_VERSION == _POSIX_)
194 		  errno = ERANGE;
195 		else if (!matherr(&exc)) {
196 			errno = ERANGE;
197 		}
198 		break;
199 	    case 8:
200 		/* y0(0) = -inf */
201 		exc.type = DOMAIN;	/* should be SING for IEEE */
202 		exc.name = "y0";
203 		if (_LIB_VERSION == _SVID_)
204 		  exc.retval = -HUGE;
205 		else
206 		  exc.retval = -HUGE_VAL;
207 		if (_LIB_VERSION == _POSIX_)
208 		  errno = EDOM;
209 		else if (!matherr(&exc)) {
210 		  if (_LIB_VERSION == _SVID_) {
211 			(void) WRITE2("y0: DOMAIN error\n", 17);
212 		      }
213 		  errno = EDOM;
214 		}
215 		break;
216 	    case 9:
217 		/* y0(x<0) = NaN */
218 		exc.type = DOMAIN;
219 		exc.name = "y0";
220 		if (_LIB_VERSION == _SVID_)
221 		  exc.retval = -HUGE;
222 		else
223 		  exc.retval = -HUGE_VAL;
224 		if (_LIB_VERSION == _POSIX_)
225 		  errno = EDOM;
226 		else if (!matherr(&exc)) {
227 		  if (_LIB_VERSION == _SVID_) {
228 			(void) WRITE2("y0: DOMAIN error\n", 17);
229 		      }
230 		  errno = EDOM;
231 		}
232 		break;
233 	    case 10:
234 		/* y1(0) = -inf */
235 		exc.type = DOMAIN;	/* should be SING for IEEE */
236 		exc.name = "y1";
237 		if (_LIB_VERSION == _SVID_)
238 		  exc.retval = -HUGE;
239 		else
240 		  exc.retval = -HUGE_VAL;
241 		if (_LIB_VERSION == _POSIX_)
242 		  errno = EDOM;
243 		else if (!matherr(&exc)) {
244 		  if (_LIB_VERSION == _SVID_) {
245 			(void) WRITE2("y1: DOMAIN error\n", 17);
246 		      }
247 		  errno = EDOM;
248 		}
249 		break;
250 	    case 11:
251 		/* y1(x<0) = NaN */
252 		exc.type = DOMAIN;
253 		exc.name = "y1";
254 		if (_LIB_VERSION == _SVID_)
255 		  exc.retval = -HUGE;
256 		else
257 		  exc.retval = -HUGE_VAL;
258 		if (_LIB_VERSION == _POSIX_)
259 		  errno = EDOM;
260 		else if (!matherr(&exc)) {
261 		  if (_LIB_VERSION == _SVID_) {
262 			(void) WRITE2("y1: DOMAIN error\n", 17);
263 		      }
264 		  errno = EDOM;
265 		}
266 		break;
267 	    case 12:
268 		/* yn(n,0) = -inf */
269 		exc.type = DOMAIN;	/* should be SING for IEEE */
270 		exc.name = "yn";
271 		if (_LIB_VERSION == _SVID_)
272 		  exc.retval = -HUGE;
273 		else
274 		  exc.retval = -HUGE_VAL;
275 		if (_LIB_VERSION == _POSIX_)
276 		  errno = EDOM;
277 		else if (!matherr(&exc)) {
278 		  if (_LIB_VERSION == _SVID_) {
279 			(void) WRITE2("yn: DOMAIN error\n", 17);
280 		      }
281 		  errno = EDOM;
282 		}
283 		break;
284 	    case 13:
285 		/* yn(x<0) = NaN */
286 		exc.type = DOMAIN;
287 		exc.name = "yn";
288 		if (_LIB_VERSION == _SVID_)
289 		  exc.retval = -HUGE;
290 		else
291 		  exc.retval = -HUGE_VAL;
292 		if (_LIB_VERSION == _POSIX_)
293 		  errno = EDOM;
294 		else if (!matherr(&exc)) {
295 		  if (_LIB_VERSION == _SVID_) {
296 			(void) WRITE2("yn: DOMAIN error\n", 17);
297 		      }
298 		  errno = EDOM;
299 		}
300 		break;
301 	    case 14:
302 		/* lgamma(finite) overflow */
303 		exc.type = OVERFLOW;
304 		exc.name = "lgamma";
305                 if (_LIB_VERSION == _SVID_)
306                   exc.retval = HUGE;
307                 else
308                   exc.retval = HUGE_VAL;
309                 if (_LIB_VERSION == _POSIX_)
310 			errno = ERANGE;
311                 else if (!matherr(&exc)) {
312                         errno = ERANGE;
313 		}
314 		break;
315 	    case 15:
316 		/* lgamma(-integer) or lgamma(0) */
317 		exc.type = SING;
318 		exc.name = "lgamma";
319                 if (_LIB_VERSION == _SVID_)
320                   exc.retval = HUGE;
321                 else
322                   exc.retval = HUGE_VAL;
323 		if (_LIB_VERSION == _POSIX_)
324 		  errno = EDOM;
325 		else if (!matherr(&exc)) {
326 		  if (_LIB_VERSION == _SVID_) {
327 			(void) WRITE2("lgamma: SING error\n", 19);
328 		      }
329 		  errno = EDOM;
330 		}
331 		break;
332 	    case 16:
333 		/* log(0) */
334 		exc.type = SING;
335 		exc.name = "log";
336 		if (_LIB_VERSION == _SVID_)
337 		  exc.retval = -HUGE;
338 		else
339 		  exc.retval = -HUGE_VAL;
340 		if (_LIB_VERSION == _POSIX_)
341 		  errno = ERANGE;
342 		else if (!matherr(&exc)) {
343 		  if (_LIB_VERSION == _SVID_) {
344 			(void) WRITE2("log: SING error\n", 16);
345 		      }
346 		  errno = EDOM;
347 		}
348 		break;
349 	    case 17:
350 		/* log(x<0) */
351 		exc.type = DOMAIN;
352 		exc.name = "log";
353 		if (_LIB_VERSION == _SVID_)
354 		  exc.retval = -HUGE;
355 		else
356 		  exc.retval = -HUGE_VAL;
357 		if (_LIB_VERSION == _POSIX_)
358 		  errno = EDOM;
359 		else if (!matherr(&exc)) {
360 		  if (_LIB_VERSION == _SVID_) {
361 			(void) WRITE2("log: DOMAIN error\n", 18);
362 		      }
363 		  errno = EDOM;
364 		}
365 		break;
366 	    case 18:
367 		/* log10(0) */
368 		exc.type = SING;
369 		exc.name = "log10";
370 		if (_LIB_VERSION == _SVID_)
371 		  exc.retval = -HUGE;
372 		else
373 		  exc.retval = -HUGE_VAL;
374 		if (_LIB_VERSION == _POSIX_)
375 		  errno = ERANGE;
376 		else if (!matherr(&exc)) {
377 		  if (_LIB_VERSION == _SVID_) {
378 			(void) WRITE2("log10: SING error\n", 18);
379 		      }
380 		  errno = EDOM;
381 		}
382 		break;
383 	    case 19:
384 		/* log10(x<0) */
385 		exc.type = DOMAIN;
386 		exc.name = "log10";
387 		if (_LIB_VERSION == _SVID_)
388 		  exc.retval = -HUGE;
389 		else
390 		  exc.retval = -HUGE_VAL;
391 		if (_LIB_VERSION == _POSIX_)
392 		  errno = EDOM;
393 		else if (!matherr(&exc)) {
394 		  if (_LIB_VERSION == _SVID_) {
395 			(void) WRITE2("log10: DOMAIN error\n", 20);
396 		      }
397 		  errno = EDOM;
398 		}
399 		break;
400 	    case 20:
401 		/* pow(0.0,0.0) */
402 		/* error only if _LIB_VERSION == _SVID_ */
403 		exc.type = DOMAIN;
404 		exc.name = "pow";
405 		exc.retval = zero;
406 		if (_LIB_VERSION != _SVID_) exc.retval = 1.0;
407 		else if (!matherr(&exc)) {
408 			(void) WRITE2("pow(0,0): DOMAIN error\n", 23);
409 			errno = EDOM;
410 		}
411 		break;
412 	    case 21:
413 		/* pow(x,y) overflow */
414 		exc.type = OVERFLOW;
415 		exc.name = "pow";
416 		if (_LIB_VERSION == _SVID_) {
417 		  exc.retval = HUGE;
418 		  y *= 0.5;
419 		  if(x<zero&&rint(y)!=y) exc.retval = -HUGE;
420 		} else {
421 		  exc.retval = HUGE_VAL;
422 		  y *= 0.5;
423 		  if(x<zero&&rint(y)!=y) exc.retval = -HUGE_VAL;
424 		}
425 		if (_LIB_VERSION == _POSIX_)
426 		  errno = ERANGE;
427 		else if (!matherr(&exc)) {
428 			errno = ERANGE;
429 		}
430 		break;
431 	    case 22:
432 		/* pow(x,y) underflow */
433 		exc.type = UNDERFLOW;
434 		exc.name = "pow";
435 		exc.retval =  zero;
436 		if (_LIB_VERSION == _POSIX_)
437 		  errno = ERANGE;
438 		else if (!matherr(&exc)) {
439 			errno = ERANGE;
440 		}
441 		break;
442 	    case 23:
443 		/* 0**neg */
444 		exc.type = DOMAIN;
445 		exc.name = "pow";
446 		if (_LIB_VERSION == _SVID_)
447 		  exc.retval = zero;
448 		else
449 		  exc.retval = -HUGE_VAL;
450 		if (_LIB_VERSION == _POSIX_)
451 		  errno = EDOM;
452 		else if (!matherr(&exc)) {
453 		  if (_LIB_VERSION == _SVID_) {
454 			(void) WRITE2("pow(0,neg): DOMAIN error\n", 25);
455 		      }
456 		  errno = EDOM;
457 		}
458 		break;
459 	    case 24:
460 		/* neg**non-integral */
461 		exc.type = DOMAIN;
462 		exc.name = "pow";
463 		if (_LIB_VERSION == _SVID_)
464 		    exc.retval = zero;
465 		else
466 		    exc.retval = zero/zero;	/* X/Open allow NaN */
467 		if (_LIB_VERSION == _POSIX_)
468 		   errno = EDOM;
469 		else if (!matherr(&exc)) {
470 		  if (_LIB_VERSION == _SVID_) {
471 			(void) WRITE2("neg**non-integral: DOMAIN error\n", 32);
472 		      }
473 		  errno = EDOM;
474 		}
475 		break;
476 	    case 25:
477 		/* sinh(finite) overflow */
478 		exc.type = OVERFLOW;
479 		exc.name = "sinh";
480 		if (_LIB_VERSION == _SVID_)
481 		  exc.retval = ( (x>zero) ? HUGE : -HUGE);
482 		else
483 		  exc.retval = ( (x>zero) ? HUGE_VAL : -HUGE_VAL);
484 		if (_LIB_VERSION == _POSIX_)
485 		  errno = ERANGE;
486 		else if (!matherr(&exc)) {
487 			errno = ERANGE;
488 		}
489 		break;
490 	    case 26:
491 		/* sqrt(x<0) */
492 		exc.type = DOMAIN;
493 		exc.name = "sqrt";
494 		if (_LIB_VERSION == _SVID_)
495 		  exc.retval = zero;
496 		else
497 		  exc.retval = zero/zero;
498 		if (_LIB_VERSION == _POSIX_)
499 		  errno = EDOM;
500 		else if (!matherr(&exc)) {
501 		  if (_LIB_VERSION == _SVID_) {
502 			(void) WRITE2("sqrt: DOMAIN error\n", 19);
503 		      }
504 		  errno = EDOM;
505 		}
506 		break;
507             case 27:
508                 /* fmod(x,0) */
509                 exc.type = DOMAIN;
510                 exc.name = "fmod";
511                 if (_LIB_VERSION == _SVID_)
512                     exc.retval = x;
513 		else
514 		    exc.retval = zero/zero;
515                 if (_LIB_VERSION == _POSIX_)
516                   errno = EDOM;
517                 else if (!matherr(&exc)) {
518                   if (_LIB_VERSION == _SVID_) {
519                     (void) WRITE2("fmod:  DOMAIN error\n", 20);
520                   }
521                   errno = EDOM;
522                 }
523                 break;
524             case 28:
525                 /* remainder(x,0) */
526                 exc.type = DOMAIN;
527                 exc.name = "remainder";
528                 exc.retval = zero/zero;
529                 if (_LIB_VERSION == _POSIX_)
530                   errno = EDOM;
531                 else if (!matherr(&exc)) {
532                   if (_LIB_VERSION == _SVID_) {
533                     (void) WRITE2("remainder: DOMAIN error\n", 24);
534                   }
535                   errno = EDOM;
536                 }
537                 break;
538             case 29:
539                 /* acosh(x<1) */
540                 exc.type = DOMAIN;
541                 exc.name = "acosh";
542                 exc.retval = zero/zero;
543                 if (_LIB_VERSION == _POSIX_)
544                   errno = EDOM;
545                 else if (!matherr(&exc)) {
546                   if (_LIB_VERSION == _SVID_) {
547                     (void) WRITE2("acosh: DOMAIN error\n", 20);
548                   }
549                   errno = EDOM;
550                 }
551                 break;
552             case 30:
553                 /* atanh(|x|>1) */
554                 exc.type = DOMAIN;
555                 exc.name = "atanh";
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("atanh: DOMAIN error\n", 20);
562                   }
563                   errno = EDOM;
564                 }
565                 break;
566             case 31:
567                 /* atanh(|x|=1) */
568                 exc.type = SING;
569                 exc.name = "atanh";
570 		exc.retval = x/zero;	/* sign(x)*inf */
571                 if (_LIB_VERSION == _POSIX_)
572                   errno = EDOM;
573                 else if (!matherr(&exc)) {
574                   if (_LIB_VERSION == _SVID_) {
575                     (void) WRITE2("atanh: SING error\n", 18);
576                   }
577                   errno = EDOM;
578                 }
579                 break;
580 	    case 32:
581 		/* scalb overflow; SVID also returns +-HUGE_VAL */
582 		exc.type = OVERFLOW;
583 		exc.name = "scalb";
584 		exc.retval = x > zero ? HUGE_VAL : -HUGE_VAL;
585 		if (_LIB_VERSION == _POSIX_)
586 		  errno = ERANGE;
587 		else if (!matherr(&exc)) {
588 			errno = ERANGE;
589 		}
590 		break;
591 	    case 33:
592 		/* scalb underflow */
593 		exc.type = UNDERFLOW;
594 		exc.name = "scalb";
595 		exc.retval = copysign(zero,x);
596 		if (_LIB_VERSION == _POSIX_)
597 		  errno = ERANGE;
598 		else if (!matherr(&exc)) {
599 			errno = ERANGE;
600 		}
601 		break;
602 	    case 34:
603 		/* j0(|x|>X_TLOSS) */
604                 exc.type = TLOSS;
605                 exc.name = "j0";
606                 exc.retval = zero;
607                 if (_LIB_VERSION == _POSIX_)
608                         errno = ERANGE;
609                 else if (!matherr(&exc)) {
610                         if (_LIB_VERSION == _SVID_) {
611                                 (void) WRITE2(exc.name, 2);
612                                 (void) WRITE2(": TLOSS error\n", 14);
613                         }
614                         errno = ERANGE;
615                 }
616 		break;
617 	    case 35:
618 		/* y0(x>X_TLOSS) */
619                 exc.type = TLOSS;
620                 exc.name = "y0";
621                 exc.retval = zero;
622                 if (_LIB_VERSION == _POSIX_)
623                         errno = ERANGE;
624                 else if (!matherr(&exc)) {
625                         if (_LIB_VERSION == _SVID_) {
626                                 (void) WRITE2(exc.name, 2);
627                                 (void) WRITE2(": TLOSS error\n", 14);
628                         }
629                         errno = ERANGE;
630                 }
631 		break;
632 	    case 36:
633 		/* j1(|x|>X_TLOSS) */
634                 exc.type = TLOSS;
635                 exc.name = "j1";
636                 exc.retval = zero;
637                 if (_LIB_VERSION == _POSIX_)
638                         errno = ERANGE;
639                 else if (!matherr(&exc)) {
640                         if (_LIB_VERSION == _SVID_) {
641                                 (void) WRITE2(exc.name, 2);
642                                 (void) WRITE2(": TLOSS error\n", 14);
643                         }
644                         errno = ERANGE;
645                 }
646 		break;
647 	    case 37:
648 		/* y1(x>X_TLOSS) */
649                 exc.type = TLOSS;
650                 exc.name = "y1";
651                 exc.retval = zero;
652                 if (_LIB_VERSION == _POSIX_)
653                         errno = ERANGE;
654                 else if (!matherr(&exc)) {
655                         if (_LIB_VERSION == _SVID_) {
656                                 (void) WRITE2(exc.name, 2);
657                                 (void) WRITE2(": TLOSS error\n", 14);
658                         }
659                         errno = ERANGE;
660                 }
661 		break;
662 	    case 38:
663 		/* jn(|x|>X_TLOSS) */
664                 exc.type = TLOSS;
665                 exc.name = "jn";
666                 exc.retval = zero;
667                 if (_LIB_VERSION == _POSIX_)
668                         errno = ERANGE;
669                 else if (!matherr(&exc)) {
670                         if (_LIB_VERSION == _SVID_) {
671                                 (void) WRITE2(exc.name, 2);
672                                 (void) WRITE2(": TLOSS error\n", 14);
673                         }
674                         errno = ERANGE;
675                 }
676 		break;
677 	    case 39:
678 		/* yn(x>X_TLOSS) */
679                 exc.type = TLOSS;
680                 exc.name = "yn";
681                 exc.retval = zero;
682                 if (_LIB_VERSION == _POSIX_)
683                         errno = ERANGE;
684                 else if (!matherr(&exc)) {
685                         if (_LIB_VERSION == _SVID_) {
686                                 (void) WRITE2(exc.name, 2);
687                                 (void) WRITE2(": TLOSS error\n", 14);
688                         }
689                         errno = ERANGE;
690                 }
691 		break;
692 	    case 40:
693 		/* gamma(finite) overflow */
694 		exc.type = OVERFLOW;
695 		exc.name = "gamma";
696                 if (_LIB_VERSION == _SVID_)
697                   exc.retval = HUGE;
698                 else
699                   exc.retval = HUGE_VAL;
700                 if (_LIB_VERSION == _POSIX_)
701 		  errno = ERANGE;
702                 else if (!matherr(&exc)) {
703                   errno = ERANGE;
704                 }
705 		break;
706 	    case 41:
707 		/* gamma(-integer) or gamma(0) */
708 		exc.type = SING;
709 		exc.name = "gamma";
710                 if (_LIB_VERSION == _SVID_)
711                   exc.retval = HUGE;
712                 else
713                   exc.retval = HUGE_VAL;
714 		if (_LIB_VERSION == _POSIX_)
715 		  errno = EDOM;
716 		else if (!matherr(&exc)) {
717 		  if (_LIB_VERSION == _SVID_) {
718 			(void) WRITE2("gamma: SING error\n", 18);
719 		      }
720 		  errno = EDOM;
721 		}
722 		break;
723 	    case 42:
724 		/* pow(NaN,0.0) */
725 		/* error only if _LIB_VERSION == _SVID_ & _XOPEN_ */
726 		exc.type = DOMAIN;
727 		exc.name = "pow";
728 		exc.retval = x;
729 		if (_LIB_VERSION == _IEEE_ ||
730 		    _LIB_VERSION == _POSIX_) exc.retval = 1.0;
731 		else if (!matherr(&exc)) {
732 			errno = EDOM;
733 		}
734 		break;
735 	}
736 	return exc.retval;
737 }
738