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