1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2  *
3  * ***** BEGIN LICENSE BLOCK *****
4  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5  *
6  * The contents of this file are subject to the Mozilla Public License Version
7  * 1.1 (the "License"); you may not use this file except in compliance with
8  * the License. You may obtain a copy of the License at
9  * http://www.mozilla.org/MPL/
10  *
11  * Software distributed under the License is distributed on an "AS IS" basis,
12  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13  * for the specific language governing rights and limitations under the
14  * License.
15  *
16  * The Original Code is Mozilla Communicator client code, released
17  * March 31, 1998.
18  *
19  * The Initial Developer of the Original Code is
20  * Sun Microsystems, Inc.
21  * Portions created by the Initial Developer are Copyright (C) 1998
22  * the Initial Developer. All Rights Reserved.
23  *
24  * Contributor(s):
25  *
26  * Alternatively, the contents of this file may be used under the terms of
27  * either of the GNU General Public License Version 2 or later (the "GPL"),
28  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29  * in which case the provisions of the GPL or the LGPL are applicable instead
30  * of those above. If you wish to allow use of your version of this file only
31  * under the terms of either the GPL or the LGPL, and not to allow others to
32  * use your version of this file under the terms of the MPL, indicate your
33  * decision by deleting the provisions above and replace them with the notice
34  * and other provisions required by the GPL or the LGPL. If you do not delete
35  * the provisions above, a recipient may use your version of this file under
36  * the terms of any one of the MPL, the GPL or the LGPL.
37  *
38  * ***** END LICENSE BLOCK ***** */
39 
40 /* @(#)k_standard.c 1.3 95/01/18 */
41 /*
42  * ====================================================
43  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
44  *
45  * Developed at SunSoft, a Sun Microsystems, Inc. business.
46  * Permission to use, copy, modify, and distribute this
47  * software is freely granted, provided that this notice
48  * is preserved.
49  * ====================================================
50  *
51  */
52 
53 #include "fdlibm.h"
54 
55 /* XXX ugly hack to get msvc to link without error. */
56 #if _LIB_VERSION == _IEEE_ && !(defined(DARWIN) || defined(XP_MACOSX) || defined(__DragonFly__))
57    int errno;
58 #  define EDOM 0
59 #  define ERANGE 0
60 #else
61 #  include <errno.h>
62 #endif
63 
64 
65 #ifndef _USE_WRITE
66 #include <stdio.h>			/* fputs(), stderr */
67 #define	WRITE2(u,v)	fputs(u, stderr)
68 #else	/* !defined(_USE_WRITE) */
69 #include <unistd.h>			/* write */
70 #define	WRITE2(u,v)	write(2, u, v)
71 #undef fflush
72 #endif	/* !defined(_USE_WRITE) */
73 
74 static double zero = 0.0;	/* used as const */
75 
76 /*
77  * Standard conformance (non-IEEE) on exception cases.
78  * Mapping:
79  *	1 -- acos(|x|>1)
80  *	2 -- asin(|x|>1)
81  *	3 -- atan2(+-0,+-0)
82  *	4 -- hypot overflow
83  *	5 -- cosh overflow
84  *	6 -- exp overflow
85  *	7 -- exp underflow
86  *	8 -- y0(0)
87  *	9 -- y0(-ve)
88  *	10-- y1(0)
89  *	11-- y1(-ve)
90  *	12-- yn(0)
91  *	13-- yn(-ve)
92  *	14-- lgamma(finite) overflow
93  *	15-- lgamma(-integer)
94  *	16-- log(0)
95  *	17-- log(x<0)
96  *	18-- log10(0)
97  *	19-- log10(x<0)
98  *	20-- pow(0.0,0.0)
99  *	21-- pow(x,y) overflow
100  *	22-- pow(x,y) underflow
101  *	23-- pow(0,negative)
102  *	24-- pow(neg,non-integral)
103  *	25-- sinh(finite) overflow
104  *	26-- sqrt(negative)
105  *      27-- fmod(x,0)
106  *      28-- remainder(x,0)
107  *	29-- acosh(x<1)
108  *	30-- atanh(|x|>1)
109  *	31-- atanh(|x|=1)
110  *	32-- scalb overflow
111  *	33-- scalb underflow
112  *	34-- j0(|x|>X_TLOSS)
113  *	35-- y0(x>X_TLOSS)
114  *	36-- j1(|x|>X_TLOSS)
115  *	37-- y1(x>X_TLOSS)
116  *	38-- jn(|x|>X_TLOSS, n)
117  *	39-- yn(x>X_TLOSS, n)
118  *	40-- gamma(finite) overflow
119  *	41-- gamma(-integer)
120  *	42-- pow(NaN,0.0)
121  */
122 
123 
124 #ifdef __STDC__
__kernel_standard(double x,double y,int type,int * err)125 	double __kernel_standard(double x, double y, int type, int *err)
126 #else
127 	double __kernel_standard(x,y,type, err)
128      double x,y; int type;int *err;
129 #endif
130 {
131 	struct exception exc;
132 #ifndef HUGE_VAL	/* this is the only routine that uses HUGE_VAL */
133 #define HUGE_VAL inf
134 	double inf = 0.0;
135         fd_twoints u;
136 
137         u.d = inf;
138 	__HI(u) = 0x7ff00000;	/* set inf to infinite */
139         inf = u.d;
140 #endif
141 
142     *err = 0;
143 
144 #ifdef _USE_WRITE
145 	(void) fflush(stdout);
146 #endif
147 	exc.arg1 = x;
148 	exc.arg2 = y;
149 	switch(type) {
150 	    case 1:
151 		/* acos(|x|>1) */
152 		exc.type = DOMAIN;
153 		exc.name = "acos";
154 		exc.retval = zero;
155 		if (_LIB_VERSION == _POSIX_)
156 		  *err = EDOM;
157 		else if (!fd_matherr(&exc)) {
158 		  if(_LIB_VERSION == _SVID_) {
159 		    (void) WRITE2("acos: DOMAIN error\n", 19);
160 		  }
161 		  *err = EDOM;
162 		}
163 		break;
164 	    case 2:
165 		/* asin(|x|>1) */
166 		exc.type = DOMAIN;
167 		exc.name = "asin";
168 		exc.retval = zero;
169 		if(_LIB_VERSION == _POSIX_)
170 		  *err = EDOM;
171 		else if (!fd_matherr(&exc)) {
172 		  if(_LIB_VERSION == _SVID_) {
173 		    	(void) WRITE2("asin: DOMAIN error\n", 19);
174 		  }
175 		  *err = EDOM;
176 		}
177 		break;
178 	    case 3:
179 		/* atan2(+-0,+-0) */
180 		exc.arg1 = y;
181 		exc.arg2 = x;
182 		exc.type = DOMAIN;
183 		exc.name = "atan2";
184 		exc.retval = zero;
185 		if(_LIB_VERSION == _POSIX_)
186 		  *err = EDOM;
187 		else if (!fd_matherr(&exc)) {
188 		  if(_LIB_VERSION == _SVID_) {
189 			(void) WRITE2("atan2: DOMAIN error\n", 20);
190 		      }
191 		  *err = EDOM;
192 		}
193 		break;
194 	    case 4:
195 		/* hypot(finite,finite) overflow */
196 		exc.type = OVERFLOW;
197 		exc.name = "hypot";
198 		if (_LIB_VERSION == _SVID_)
199 		  exc.retval = HUGE;
200 		else
201 		  exc.retval = HUGE_VAL;
202 		if (_LIB_VERSION == _POSIX_)
203 		  *err = ERANGE;
204 		else if (!fd_matherr(&exc)) {
205 			*err = ERANGE;
206 		}
207 		break;
208 	    case 5:
209 		/* cosh(finite) overflow */
210 		exc.type = OVERFLOW;
211 		exc.name = "cosh";
212 		if (_LIB_VERSION == _SVID_)
213 		  exc.retval = HUGE;
214 		else
215 		  exc.retval = HUGE_VAL;
216 		if (_LIB_VERSION == _POSIX_)
217 		  *err = ERANGE;
218 		else if (!fd_matherr(&exc)) {
219 			*err = ERANGE;
220 		}
221 		break;
222 	    case 6:
223 		/* exp(finite) overflow */
224 		exc.type = OVERFLOW;
225 		exc.name = "exp";
226 		if (_LIB_VERSION == _SVID_)
227 		  exc.retval = HUGE;
228 		else
229 		  exc.retval = HUGE_VAL;
230 		if (_LIB_VERSION == _POSIX_)
231 		  *err = ERANGE;
232 		else if (!fd_matherr(&exc)) {
233 			*err = ERANGE;
234 		}
235 		break;
236 	    case 7:
237 		/* exp(finite) underflow */
238 		exc.type = UNDERFLOW;
239 		exc.name = "exp";
240 		exc.retval = zero;
241 		if (_LIB_VERSION == _POSIX_)
242 		  *err = ERANGE;
243 		else if (!fd_matherr(&exc)) {
244 			*err = ERANGE;
245 		}
246 		break;
247 	    case 8:
248 		/* y0(0) = -inf */
249 		exc.type = DOMAIN;	/* should be SING for IEEE */
250 		exc.name = "y0";
251 		if (_LIB_VERSION == _SVID_)
252 		  exc.retval = -HUGE;
253 		else
254 		  exc.retval = -HUGE_VAL;
255 		if (_LIB_VERSION == _POSIX_)
256 		  *err = EDOM;
257 		else if (!fd_matherr(&exc)) {
258 		  if (_LIB_VERSION == _SVID_) {
259 			(void) WRITE2("y0: DOMAIN error\n", 17);
260 		      }
261 		  *err = EDOM;
262 		}
263 		break;
264 	    case 9:
265 		/* y0(x<0) = NaN */
266 		exc.type = DOMAIN;
267 		exc.name = "y0";
268 		if (_LIB_VERSION == _SVID_)
269 		  exc.retval = -HUGE;
270 		else
271 		  exc.retval = -HUGE_VAL;
272 		if (_LIB_VERSION == _POSIX_)
273 		  *err = EDOM;
274 		else if (!fd_matherr(&exc)) {
275 		  if (_LIB_VERSION == _SVID_) {
276 			(void) WRITE2("y0: DOMAIN error\n", 17);
277 		      }
278 		  *err = EDOM;
279 		}
280 		break;
281 	    case 10:
282 		/* y1(0) = -inf */
283 		exc.type = DOMAIN;	/* should be SING for IEEE */
284 		exc.name = "y1";
285 		if (_LIB_VERSION == _SVID_)
286 		  exc.retval = -HUGE;
287 		else
288 		  exc.retval = -HUGE_VAL;
289 		if (_LIB_VERSION == _POSIX_)
290 		  *err = EDOM;
291 		else if (!fd_matherr(&exc)) {
292 		  if (_LIB_VERSION == _SVID_) {
293 			(void) WRITE2("y1: DOMAIN error\n", 17);
294 		      }
295 		  *err = EDOM;
296 		}
297 		break;
298 	    case 11:
299 		/* y1(x<0) = NaN */
300 		exc.type = DOMAIN;
301 		exc.name = "y1";
302 		if (_LIB_VERSION == _SVID_)
303 		  exc.retval = -HUGE;
304 		else
305 		  exc.retval = -HUGE_VAL;
306 		if (_LIB_VERSION == _POSIX_)
307 		  *err = EDOM;
308 		else if (!fd_matherr(&exc)) {
309 		  if (_LIB_VERSION == _SVID_) {
310 			(void) WRITE2("y1: DOMAIN error\n", 17);
311 		      }
312 		  *err = EDOM;
313 		}
314 		break;
315 	    case 12:
316 		/* yn(n,0) = -inf */
317 		exc.type = DOMAIN;	/* should be SING for IEEE */
318 		exc.name = "yn";
319 		if (_LIB_VERSION == _SVID_)
320 		  exc.retval = -HUGE;
321 		else
322 		  exc.retval = -HUGE_VAL;
323 		if (_LIB_VERSION == _POSIX_)
324 		  *err = EDOM;
325 		else if (!fd_matherr(&exc)) {
326 		  if (_LIB_VERSION == _SVID_) {
327 			(void) WRITE2("yn: DOMAIN error\n", 17);
328 		      }
329 		  *err = EDOM;
330 		}
331 		break;
332 	    case 13:
333 		/* yn(x<0) = NaN */
334 		exc.type = DOMAIN;
335 		exc.name = "yn";
336 		if (_LIB_VERSION == _SVID_)
337 		  exc.retval = -HUGE;
338 		else
339 		  exc.retval = -HUGE_VAL;
340 		if (_LIB_VERSION == _POSIX_)
341 		  *err = EDOM;
342 		else if (!fd_matherr(&exc)) {
343 		  if (_LIB_VERSION == _SVID_) {
344 			(void) WRITE2("yn: DOMAIN error\n", 17);
345 		      }
346 		  *err = EDOM;
347 		}
348 		break;
349 	    case 14:
350 		/* lgamma(finite) overflow */
351 		exc.type = OVERFLOW;
352 		exc.name = "lgamma";
353                 if (_LIB_VERSION == _SVID_)
354                   exc.retval = HUGE;
355                 else
356                   exc.retval = HUGE_VAL;
357                 if (_LIB_VERSION == _POSIX_)
358 			*err = ERANGE;
359                 else if (!fd_matherr(&exc)) {
360                         *err = ERANGE;
361 		}
362 		break;
363 	    case 15:
364 		/* lgamma(-integer) or lgamma(0) */
365 		exc.type = SING;
366 		exc.name = "lgamma";
367                 if (_LIB_VERSION == _SVID_)
368                   exc.retval = HUGE;
369                 else
370                   exc.retval = HUGE_VAL;
371 		if (_LIB_VERSION == _POSIX_)
372 		  *err = EDOM;
373 		else if (!fd_matherr(&exc)) {
374 		  if (_LIB_VERSION == _SVID_) {
375 			(void) WRITE2("lgamma: SING error\n", 19);
376 		      }
377 		  *err = EDOM;
378 		}
379 		break;
380 	    case 16:
381 		/* log(0) */
382 		exc.type = SING;
383 		exc.name = "log";
384 		if (_LIB_VERSION == _SVID_)
385 		  exc.retval = -HUGE;
386 		else
387 		  exc.retval = -HUGE_VAL;
388 		if (_LIB_VERSION == _POSIX_)
389 		  *err = ERANGE;
390 		else if (!fd_matherr(&exc)) {
391 		  if (_LIB_VERSION == _SVID_) {
392 			(void) WRITE2("log: SING error\n", 16);
393 		      }
394 		  *err = EDOM;
395 		}
396 		break;
397 	    case 17:
398 		/* log(x<0) */
399 		exc.type = DOMAIN;
400 		exc.name = "log";
401 		if (_LIB_VERSION == _SVID_)
402 		  exc.retval = -HUGE;
403 		else
404 		  exc.retval = -HUGE_VAL;
405 		if (_LIB_VERSION == _POSIX_)
406 		  *err = EDOM;
407 		else if (!fd_matherr(&exc)) {
408 		  if (_LIB_VERSION == _SVID_) {
409 			(void) WRITE2("log: DOMAIN error\n", 18);
410 		      }
411 		  *err = EDOM;
412 		}
413 		break;
414 	    case 18:
415 		/* log10(0) */
416 		exc.type = SING;
417 		exc.name = "log10";
418 		if (_LIB_VERSION == _SVID_)
419 		  exc.retval = -HUGE;
420 		else
421 		  exc.retval = -HUGE_VAL;
422 		if (_LIB_VERSION == _POSIX_)
423 		  *err = ERANGE;
424 		else if (!fd_matherr(&exc)) {
425 		  if (_LIB_VERSION == _SVID_) {
426 			(void) WRITE2("log10: SING error\n", 18);
427 		      }
428 		  *err = EDOM;
429 		}
430 		break;
431 	    case 19:
432 		/* log10(x<0) */
433 		exc.type = DOMAIN;
434 		exc.name = "log10";
435 		if (_LIB_VERSION == _SVID_)
436 		  exc.retval = -HUGE;
437 		else
438 		  exc.retval = -HUGE_VAL;
439 		if (_LIB_VERSION == _POSIX_)
440 		  *err = EDOM;
441 		else if (!fd_matherr(&exc)) {
442 		  if (_LIB_VERSION == _SVID_) {
443 			(void) WRITE2("log10: DOMAIN error\n", 20);
444 		      }
445 		  *err = EDOM;
446 		}
447 		break;
448 	    case 20:
449 		/* pow(0.0,0.0) */
450 		/* error only if _LIB_VERSION == _SVID_ */
451 		exc.type = DOMAIN;
452 		exc.name = "pow";
453 		exc.retval = zero;
454 		if (_LIB_VERSION != _SVID_) exc.retval = 1.0;
455 		else if (!fd_matherr(&exc)) {
456 			(void) WRITE2("pow(0,0): DOMAIN error\n", 23);
457 			*err = EDOM;
458 		}
459 		break;
460 	    case 21:
461 		/* pow(x,y) overflow */
462 		exc.type = OVERFLOW;
463 		exc.name = "pow";
464 		if (_LIB_VERSION == _SVID_) {
465 		  exc.retval = HUGE;
466 		  y *= 0.5;
467 		  if(x<zero&&fd_rint(y)!=y) exc.retval = -HUGE;
468 		} else {
469 		  exc.retval = HUGE_VAL;
470 		  y *= 0.5;
471 		  if(x<zero&&fd_rint(y)!=y) exc.retval = -HUGE_VAL;
472 		}
473 		if (_LIB_VERSION == _POSIX_)
474 		  *err = ERANGE;
475 		else if (!fd_matherr(&exc)) {
476 			*err = ERANGE;
477 		}
478 		break;
479 	    case 22:
480 		/* pow(x,y) underflow */
481 		exc.type = UNDERFLOW;
482 		exc.name = "pow";
483 		exc.retval =  zero;
484 		if (_LIB_VERSION == _POSIX_)
485 		  *err = ERANGE;
486 		else if (!fd_matherr(&exc)) {
487 			*err = ERANGE;
488 		}
489 		break;
490 	    case 23:
491 		/* 0**neg */
492 		exc.type = DOMAIN;
493 		exc.name = "pow";
494 		if (_LIB_VERSION == _SVID_)
495 		  exc.retval = zero;
496 		else
497 		  exc.retval = -HUGE_VAL;
498 		if (_LIB_VERSION == _POSIX_)
499 		  *err = EDOM;
500 		else if (!fd_matherr(&exc)) {
501 		  if (_LIB_VERSION == _SVID_) {
502 			(void) WRITE2("pow(0,neg): DOMAIN error\n", 25);
503 		      }
504 		  *err = EDOM;
505 		}
506 		break;
507 	    case 24:
508 		/* neg**non-integral */
509 		exc.type = DOMAIN;
510 		exc.name = "pow";
511 		if (_LIB_VERSION == _SVID_)
512 		    exc.retval = zero;
513 		else
514 		    exc.retval = zero/zero;	/* X/Open allow NaN */
515 		if (_LIB_VERSION == _POSIX_)
516 		   *err = EDOM;
517 		else if (!fd_matherr(&exc)) {
518 		  if (_LIB_VERSION == _SVID_) {
519 			(void) WRITE2("neg**non-integral: DOMAIN error\n", 32);
520 		      }
521 		  *err = EDOM;
522 		}
523 		break;
524 	    case 25:
525 		/* sinh(finite) overflow */
526 		exc.type = OVERFLOW;
527 		exc.name = "sinh";
528 		if (_LIB_VERSION == _SVID_)
529 		  exc.retval = ( (x>zero) ? HUGE : -HUGE);
530 		else
531 		  exc.retval = ( (x>zero) ? HUGE_VAL : -HUGE_VAL);
532 		if (_LIB_VERSION == _POSIX_)
533 		  *err = ERANGE;
534 		else if (!fd_matherr(&exc)) {
535 			*err = ERANGE;
536 		}
537 		break;
538 	    case 26:
539 		/* sqrt(x<0) */
540 		exc.type = DOMAIN;
541 		exc.name = "sqrt";
542 		if (_LIB_VERSION == _SVID_)
543 		  exc.retval = zero;
544 		else
545 		  exc.retval = zero/zero;
546 		if (_LIB_VERSION == _POSIX_)
547 		  *err = EDOM;
548 		else if (!fd_matherr(&exc)) {
549 		  if (_LIB_VERSION == _SVID_) {
550 			(void) WRITE2("sqrt: DOMAIN error\n", 19);
551 		      }
552 		  *err = EDOM;
553 		}
554 		break;
555             case 27:
556                 /* fmod(x,0) */
557                 exc.type = DOMAIN;
558                 exc.name = "fmod";
559                 if (_LIB_VERSION == _SVID_)
560                     exc.retval = x;
561 		else
562 		    exc.retval = zero/zero;
563                 if (_LIB_VERSION == _POSIX_)
564                   *err = EDOM;
565                 else if (!fd_matherr(&exc)) {
566                   if (_LIB_VERSION == _SVID_) {
567                     (void) WRITE2("fmod:  DOMAIN error\n", 20);
568                   }
569                   *err = EDOM;
570                 }
571                 break;
572             case 28:
573                 /* remainder(x,0) */
574                 exc.type = DOMAIN;
575                 exc.name = "remainder";
576                 exc.retval = zero/zero;
577                 if (_LIB_VERSION == _POSIX_)
578                   *err = EDOM;
579                 else if (!fd_matherr(&exc)) {
580                   if (_LIB_VERSION == _SVID_) {
581                     (void) WRITE2("remainder: DOMAIN error\n", 24);
582                   }
583                   *err = EDOM;
584                 }
585                 break;
586             case 29:
587                 /* acosh(x<1) */
588                 exc.type = DOMAIN;
589                 exc.name = "acosh";
590                 exc.retval = zero/zero;
591                 if (_LIB_VERSION == _POSIX_)
592                   *err = EDOM;
593                 else if (!fd_matherr(&exc)) {
594                   if (_LIB_VERSION == _SVID_) {
595                     (void) WRITE2("acosh: DOMAIN error\n", 20);
596                   }
597                   *err = EDOM;
598                 }
599                 break;
600             case 30:
601                 /* atanh(|x|>1) */
602                 exc.type = DOMAIN;
603                 exc.name = "atanh";
604                 exc.retval = zero/zero;
605                 if (_LIB_VERSION == _POSIX_)
606                   *err = EDOM;
607                 else if (!fd_matherr(&exc)) {
608                   if (_LIB_VERSION == _SVID_) {
609                     (void) WRITE2("atanh: DOMAIN error\n", 20);
610                   }
611                   *err = EDOM;
612                 }
613                 break;
614             case 31:
615                 /* atanh(|x|=1) */
616                 exc.type = SING;
617                 exc.name = "atanh";
618 		exc.retval = x/zero;	/* sign(x)*inf */
619                 if (_LIB_VERSION == _POSIX_)
620                   *err = EDOM;
621                 else if (!fd_matherr(&exc)) {
622                   if (_LIB_VERSION == _SVID_) {
623                     (void) WRITE2("atanh: SING error\n", 18);
624                   }
625                   *err = EDOM;
626                 }
627                 break;
628 	    case 32:
629 		/* scalb overflow; SVID also returns +-HUGE_VAL */
630 		exc.type = OVERFLOW;
631 		exc.name = "scalb";
632 		exc.retval = x > zero ? HUGE_VAL : -HUGE_VAL;
633 		if (_LIB_VERSION == _POSIX_)
634 		  *err = ERANGE;
635 		else if (!fd_matherr(&exc)) {
636 			*err = ERANGE;
637 		}
638 		break;
639 	    case 33:
640 		/* scalb underflow */
641 		exc.type = UNDERFLOW;
642 		exc.name = "scalb";
643 		exc.retval = fd_copysign(zero,x);
644 		if (_LIB_VERSION == _POSIX_)
645 		  *err = ERANGE;
646 		else if (!fd_matherr(&exc)) {
647 			*err = ERANGE;
648 		}
649 		break;
650 	    case 34:
651 		/* j0(|x|>X_TLOSS) */
652                 exc.type = TLOSS;
653                 exc.name = "j0";
654                 exc.retval = zero;
655                 if (_LIB_VERSION == _POSIX_)
656                         *err = ERANGE;
657                 else if (!fd_matherr(&exc)) {
658                         if (_LIB_VERSION == _SVID_) {
659                                 (void) WRITE2(exc.name, 2);
660                                 (void) WRITE2(": TLOSS error\n", 14);
661                         }
662                         *err = ERANGE;
663                 }
664 		break;
665 	    case 35:
666 		/* y0(x>X_TLOSS) */
667                 exc.type = TLOSS;
668                 exc.name = "y0";
669                 exc.retval = zero;
670                 if (_LIB_VERSION == _POSIX_)
671                         *err = ERANGE;
672                 else if (!fd_matherr(&exc)) {
673                         if (_LIB_VERSION == _SVID_) {
674                                 (void) WRITE2(exc.name, 2);
675                                 (void) WRITE2(": TLOSS error\n", 14);
676                         }
677                         *err = ERANGE;
678                 }
679 		break;
680 	    case 36:
681 		/* j1(|x|>X_TLOSS) */
682                 exc.type = TLOSS;
683                 exc.name = "j1";
684                 exc.retval = zero;
685                 if (_LIB_VERSION == _POSIX_)
686                         *err = ERANGE;
687                 else if (!fd_matherr(&exc)) {
688                         if (_LIB_VERSION == _SVID_) {
689                                 (void) WRITE2(exc.name, 2);
690                                 (void) WRITE2(": TLOSS error\n", 14);
691                         }
692                         *err = ERANGE;
693                 }
694 		break;
695 	    case 37:
696 		/* y1(x>X_TLOSS) */
697                 exc.type = TLOSS;
698                 exc.name = "y1";
699                 exc.retval = zero;
700                 if (_LIB_VERSION == _POSIX_)
701                         *err = ERANGE;
702                 else if (!fd_matherr(&exc)) {
703                         if (_LIB_VERSION == _SVID_) {
704                                 (void) WRITE2(exc.name, 2);
705                                 (void) WRITE2(": TLOSS error\n", 14);
706                         }
707                         *err = ERANGE;
708                 }
709 		break;
710 	    case 38:
711 		/* jn(|x|>X_TLOSS) */
712                 exc.type = TLOSS;
713                 exc.name = "jn";
714                 exc.retval = zero;
715                 if (_LIB_VERSION == _POSIX_)
716                         *err = ERANGE;
717                 else if (!fd_matherr(&exc)) {
718                         if (_LIB_VERSION == _SVID_) {
719                                 (void) WRITE2(exc.name, 2);
720                                 (void) WRITE2(": TLOSS error\n", 14);
721                         }
722                         *err = ERANGE;
723                 }
724 		break;
725 	    case 39:
726 		/* yn(x>X_TLOSS) */
727                 exc.type = TLOSS;
728                 exc.name = "yn";
729                 exc.retval = zero;
730                 if (_LIB_VERSION == _POSIX_)
731                         *err = ERANGE;
732                 else if (!fd_matherr(&exc)) {
733                         if (_LIB_VERSION == _SVID_) {
734                                 (void) WRITE2(exc.name, 2);
735                                 (void) WRITE2(": TLOSS error\n", 14);
736                         }
737                         *err = ERANGE;
738                 }
739 		break;
740 	    case 40:
741 		/* gamma(finite) overflow */
742 		exc.type = OVERFLOW;
743 		exc.name = "gamma";
744                 if (_LIB_VERSION == _SVID_)
745                   exc.retval = HUGE;
746                 else
747                   exc.retval = HUGE_VAL;
748                 if (_LIB_VERSION == _POSIX_)
749 		  *err = ERANGE;
750                 else if (!fd_matherr(&exc)) {
751                   *err = ERANGE;
752                 }
753 		break;
754 	    case 41:
755 		/* gamma(-integer) or gamma(0) */
756 		exc.type = SING;
757 		exc.name = "gamma";
758                 if (_LIB_VERSION == _SVID_)
759                   exc.retval = HUGE;
760                 else
761                   exc.retval = HUGE_VAL;
762 		if (_LIB_VERSION == _POSIX_)
763 		  *err = EDOM;
764 		else if (!fd_matherr(&exc)) {
765 		  if (_LIB_VERSION == _SVID_) {
766 			(void) WRITE2("gamma: SING error\n", 18);
767 		      }
768 		  *err = EDOM;
769 		}
770 		break;
771 	    case 42:
772 		/* pow(NaN,0.0) */
773 		/* error only if _LIB_VERSION == _SVID_ & _XOPEN_ */
774 		exc.type = DOMAIN;
775 		exc.name = "pow";
776 		exc.retval = x;
777 		if (_LIB_VERSION == _IEEE_ ||
778 		    _LIB_VERSION == _POSIX_) exc.retval = 1.0;
779 		else if (!fd_matherr(&exc)) {
780 			*err = EDOM;
781 		}
782 		break;
783 	}
784 	return exc.retval;
785 }
786