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