xref: /minix/lib/libm/src/k_standard.c (revision 84d9c625)
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.19 2013/11/19 19:24:34 joerg 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 		if (_LIB_VERSION == _POSIX_)
474 		  errno = EDOM;
475 		else if (!matherr(&exc)) {
476 		  if (_LIB_VERSION == _SVID_) {
477 			(void) WRITE2("pow(0,neg): DOMAIN error\n", 25);
478 		      }
479 		  errno = EDOM;
480 		}
481 		break;
482 	    case 24:
483 	    case 124:
484 		/* neg**non-integral */
485 		exc.type = DOMAIN;
486 		exc.name = type < 100 ? "pow" : "powf";
487 		if (_LIB_VERSION == _SVID_)
488 		    exc.retval = zero;
489 		else
490 		    exc.retval = zero/zero;	/* X/Open allow NaN */
491 		if (_LIB_VERSION == _POSIX_)
492 		   errno = EDOM;
493 		else if (!matherr(&exc)) {
494 		  if (_LIB_VERSION == _SVID_) {
495 			(void) WRITE2("neg**non-integral: DOMAIN error\n", 32);
496 		      }
497 		  errno = EDOM;
498 		}
499 		break;
500 	    case 25:
501 	    case 125:
502 		/* sinh(finite) overflow */
503 		exc.type = OVERFLOW;
504 		exc.name = type < 100 ? "sinh" : "sinhf";
505 		if (_LIB_VERSION == _SVID_)
506 		  exc.retval = ( (x>zero) ? HUGE : -HUGE);
507 		else
508 		  exc.retval = ( (x>zero) ? HUGE_VAL : -HUGE_VAL);
509 		if (_LIB_VERSION == _POSIX_)
510 		  errno = ERANGE;
511 		else if (!matherr(&exc)) {
512 			errno = ERANGE;
513 		}
514 		break;
515 	    case 26:
516 	    case 126:
517 	    case 226:
518 		/* sqrt(x<0) */
519 		exc.type = DOMAIN;
520 		if (type == 26)
521 			exc.name = "sqrt";
522 		else if (type == 126)
523 			exc.name = "sqrtf";
524 		else
525 			exc.name = "sqrtl";
526 		if (_LIB_VERSION == _SVID_)
527 		  exc.retval = zero;
528 		else
529 		  exc.retval = zero/zero;
530 		if (_LIB_VERSION == _POSIX_)
531 		  errno = EDOM;
532 		else if (!matherr(&exc)) {
533 		  if (_LIB_VERSION == _SVID_) {
534 			(void) WRITE2("sqrt: DOMAIN error\n", 19);
535 		      }
536 		  errno = EDOM;
537 		}
538 		break;
539             case 27:
540 	    case 127:
541 	    case 227:
542                 /* fmod(x,0) */
543                 exc.type = DOMAIN;
544 		if (type == 27)
545 			exc.name = "fmod";
546 		else if (type == 127)
547 			exc.name = "fmodf";
548 		else
549 			exc.name = "fmodl";
550                 if (_LIB_VERSION == _SVID_)
551                     exc.retval = x;
552 		else
553 		    exc.retval = zero/zero;
554                 if (_LIB_VERSION == _POSIX_)
555                   errno = EDOM;
556                 else if (!matherr(&exc)) {
557                   if (_LIB_VERSION == _SVID_) {
558                     (void) WRITE2("fmod:  DOMAIN error\n", 20);
559                   }
560                   errno = EDOM;
561                 }
562                 break;
563             case 28:
564 	    case 128:
565                 /* remainder(x,0) */
566                 exc.type = DOMAIN;
567                 exc.name = type < 100 ? "remainder" : "remainderf";
568                 exc.retval = zero/zero;
569                 if (_LIB_VERSION == _POSIX_)
570                   errno = EDOM;
571                 else if (!matherr(&exc)) {
572                   if (_LIB_VERSION == _SVID_) {
573                     (void) WRITE2("remainder: DOMAIN error\n", 24);
574                   }
575                   errno = EDOM;
576                 }
577                 break;
578             case 29:
579 	    case 129:
580                 /* acosh(x<1) */
581                 exc.type = DOMAIN;
582                 exc.name = type < 100 ? "acosh" : "acoshf";
583                 exc.retval = zero/zero;
584                 if (_LIB_VERSION == _POSIX_)
585                   errno = EDOM;
586                 else if (!matherr(&exc)) {
587                   if (_LIB_VERSION == _SVID_) {
588                     (void) WRITE2("acosh: DOMAIN error\n", 20);
589                   }
590                   errno = EDOM;
591                 }
592                 break;
593             case 30:
594 	    case 130:
595                 /* atanh(|x|>1) */
596                 exc.type = DOMAIN;
597                 exc.name = type < 100 ? "atanh" : "atanhf";
598                 exc.retval = zero/zero;
599                 if (_LIB_VERSION == _POSIX_)
600                   errno = EDOM;
601                 else if (!matherr(&exc)) {
602                   if (_LIB_VERSION == _SVID_) {
603                     (void) WRITE2("atanh: DOMAIN error\n", 20);
604                   }
605                   errno = EDOM;
606                 }
607                 break;
608             case 31:
609 	    case 131:
610                 /* atanh(|x|=1) */
611                 exc.type = SING;
612                 exc.name = type < 100 ? "atanh" : "atanhf";
613 		exc.retval = x/zero;	/* sign(x)*inf */
614                 if (_LIB_VERSION == _POSIX_)
615                   errno = EDOM;
616                 else if (!matherr(&exc)) {
617                   if (_LIB_VERSION == _SVID_) {
618                     (void) WRITE2("atanh: SING error\n", 18);
619                   }
620                   errno = EDOM;
621                 }
622                 break;
623 	    case 32:
624 	    case 132:
625 		/* scalb overflow; SVID also returns +-HUGE_VAL */
626 		exc.type = OVERFLOW;
627 		exc.name = type < 100 ? "scalb" : "scalbf";
628 		exc.retval = x > zero ? HUGE_VAL : -HUGE_VAL;
629 		if (_LIB_VERSION == _POSIX_)
630 		  errno = ERANGE;
631 		else if (!matherr(&exc)) {
632 			errno = ERANGE;
633 		}
634 		break;
635 	    case 33:
636 	    case 133:
637 		/* scalb underflow */
638 		exc.type = UNDERFLOW;
639 		exc.name = type < 100 ? "scalb" : "scalbf";
640 		exc.retval = copysign(zero,x);
641 		if (_LIB_VERSION == _POSIX_)
642 		  errno = ERANGE;
643 		else if (!matherr(&exc)) {
644 			errno = ERANGE;
645 		}
646 		break;
647 	    case 34:
648 	    case 134:
649 		/* j0(|x|>X_TLOSS) */
650                 exc.type = TLOSS;
651                 exc.name = type < 100 ? "j0" : "j0f";
652                 exc.retval = zero;
653                 if (_LIB_VERSION == _POSIX_)
654                         errno = ERANGE;
655                 else if (!matherr(&exc)) {
656                         if (_LIB_VERSION == _SVID_) {
657                                 (void) WRITE2(exc.name, 2);
658                                 (void) WRITE2(": TLOSS error\n", 14);
659                         }
660                         errno = ERANGE;
661                 }
662 		break;
663 	    case 35:
664 	    case 135:
665 		/* y0(x>X_TLOSS) */
666                 exc.type = TLOSS;
667                 exc.name = type < 100 ? "y0" : "y0f";
668                 exc.retval = zero;
669                 if (_LIB_VERSION == _POSIX_)
670                         errno = ERANGE;
671                 else if (!matherr(&exc)) {
672                         if (_LIB_VERSION == _SVID_) {
673                                 (void) WRITE2(exc.name, 2);
674                                 (void) WRITE2(": TLOSS error\n", 14);
675                         }
676                         errno = ERANGE;
677                 }
678 		break;
679 	    case 36:
680 	    case 136:
681 		/* j1(|x|>X_TLOSS) */
682                 exc.type = TLOSS;
683                 exc.name = type < 100 ? "j1" : "j1f";
684                 exc.retval = zero;
685                 if (_LIB_VERSION == _POSIX_)
686                         errno = ERANGE;
687                 else if (!matherr(&exc)) {
688                         if (_LIB_VERSION == _SVID_) {
689                                 (void) WRITE2(exc.name, 2);
690                                 (void) WRITE2(": TLOSS error\n", 14);
691                         }
692                         errno = ERANGE;
693                 }
694 		break;
695 	    case 37:
696 	    case 137:
697 		/* y1(x>X_TLOSS) */
698                 exc.type = TLOSS;
699                 exc.name = type < 100 ? "y1" : "y1f";
700                 exc.retval = zero;
701                 if (_LIB_VERSION == _POSIX_)
702                         errno = ERANGE;
703                 else if (!matherr(&exc)) {
704                         if (_LIB_VERSION == _SVID_) {
705                                 (void) WRITE2(exc.name, 2);
706                                 (void) WRITE2(": TLOSS error\n", 14);
707                         }
708                         errno = ERANGE;
709                 }
710 		break;
711 	    case 38:
712 	    case 138:
713 		/* jn(|x|>X_TLOSS) */
714                 exc.type = TLOSS;
715                 exc.name = type < 100 ? "jn" : "jnf";
716                 exc.retval = zero;
717                 if (_LIB_VERSION == _POSIX_)
718                         errno = ERANGE;
719                 else if (!matherr(&exc)) {
720                         if (_LIB_VERSION == _SVID_) {
721                                 (void) WRITE2(exc.name, 2);
722                                 (void) WRITE2(": TLOSS error\n", 14);
723                         }
724                         errno = ERANGE;
725                 }
726 		break;
727 	    case 39:
728 	    case 139:
729 		/* yn(x>X_TLOSS) */
730                 exc.type = TLOSS;
731                 exc.name = type < 100 ? "yn" : "ynf";
732                 exc.retval = zero;
733                 if (_LIB_VERSION == _POSIX_)
734                         errno = ERANGE;
735                 else if (!matherr(&exc)) {
736                         if (_LIB_VERSION == _SVID_) {
737                                 (void) WRITE2(exc.name, 2);
738                                 (void) WRITE2(": TLOSS error\n", 14);
739                         }
740                         errno = ERANGE;
741                 }
742 		break;
743 	    case 40:
744 	    case 140:
745 		/* gamma(finite) overflow */
746 		exc.type = OVERFLOW;
747 		exc.name = type < 100 ? "gamma" : "gammaf";
748                 if (_LIB_VERSION == _SVID_)
749                   exc.retval = HUGE;
750                 else
751                   exc.retval = HUGE_VAL;
752                 if (_LIB_VERSION == _POSIX_)
753 		  errno = ERANGE;
754                 else if (!matherr(&exc)) {
755                   errno = ERANGE;
756                 }
757 		break;
758 	    case 41:
759 	    case 141:
760 		/* gamma(-integer) or gamma(0) */
761 		exc.type = SING;
762 		exc.name = type < 100 ? "gamma" : "gammaf";
763                 if (_LIB_VERSION == _SVID_)
764                   exc.retval = HUGE;
765                 else
766                   exc.retval = HUGE_VAL;
767 		if (_LIB_VERSION == _POSIX_)
768 		  errno = EDOM;
769 		else if (!matherr(&exc)) {
770 		  if (_LIB_VERSION == _SVID_) {
771 			(void) WRITE2("gamma: SING error\n", 18);
772 		      }
773 		  errno = EDOM;
774 		}
775 		break;
776 	    case 42:
777 	    case 142:
778 		/* pow(NaN,0.0) */
779 		/* error only if _LIB_VERSION == _SVID_ & _XOPEN_ */
780 		exc.type = DOMAIN;
781 		exc.name = type < 100 ? "pow" : "powf";
782 		exc.retval = x;
783 		if (_LIB_VERSION == _IEEE_ ||
784 		    _LIB_VERSION == _POSIX_) exc.retval = 1.0;
785 		else if (!matherr(&exc)) {
786 			errno = EDOM;
787 		}
788 		break;
789 	    case 48:
790 	    case 148:
791 		/* log2(0) */
792 		exc.type = SING;
793 		exc.name = type < 100 ? "log2" : "log2f";
794 		if (_LIB_VERSION == _SVID_)
795 		  exc.retval = -HUGE;
796 		else
797 		  exc.retval = -HUGE_VAL;
798 		if (_LIB_VERSION == _POSIX_)
799 		  errno = ERANGE;
800 		else if (!matherr(&exc)) {
801 		  if (_LIB_VERSION == _SVID_) {
802 			(void) WRITE2("log2: SING error\n", 18);
803 		      }
804 		  errno = EDOM;
805 		}
806 		break;
807 	    case 49:
808 	    case 149:
809 		/* log2(x<0) */
810 		exc.type = DOMAIN;
811 		exc.name = type < 100 ? "log2" : "log2f";
812 		if (_LIB_VERSION == _SVID_)
813 		  exc.retval = -HUGE;
814 		else
815 		  exc.retval = zero/zero;
816 		if (_LIB_VERSION == _POSIX_)
817 		  errno = EDOM;
818 		else if (!matherr(&exc)) {
819 		  if (_LIB_VERSION == _SVID_) {
820 			(void) WRITE2("log2: DOMAIN error\n", 20);
821 		      }
822 		  errno = EDOM;
823 		}
824 		break;
825 	}
826 	return exc.retval;
827 }
828