1 /*
2  * Copyright (c) 1998, 2001, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 
26 #include "fdlibm.h"
27 #include <errno.h>
28 
29 #ifndef _USE_WRITE
30 #include <stdio.h>                      /* fputs(), stderr */
31 #define WRITE2(u,v)     fputs(u, stderr)
32 #else   /* !defined(_USE_WRITE) */
33 #include <unistd.h>                     /* write */
34 #define WRITE2(u,v)     write(2, u, v)
35 #undef fflush
36 #endif  /* !defined(_USE_WRITE) */
37 
38 static double zero = 0.0;       /* used as const */
39 
40 /*
41  * Standard conformance (non-IEEE) on exception cases.
42  * Mapping:
43  *      1 -- acos(|x|>1)
44  *      2 -- asin(|x|>1)
45  *      3 -- atan2(+-0,+-0)
46  *      4 -- hypot overflow
47  *      5 -- cosh overflow
48  *      6 -- exp overflow
49  *      7 -- exp underflow
50  *      8 -- y0(0)
51  *      9 -- y0(-ve)
52  *      10-- y1(0)
53  *      11-- y1(-ve)
54  *      12-- yn(0)
55  *      13-- yn(-ve)
56  *      14-- lgamma(finite) overflow
57  *      15-- lgamma(-integer)
58  *      16-- log(0)
59  *      17-- log(x<0)
60  *      18-- log10(0)
61  *      19-- log10(x<0)
62  *      20-- pow(0.0,0.0)
63  *      21-- pow(x,y) overflow
64  *      22-- pow(x,y) underflow
65  *      23-- pow(0,negative)
66  *      24-- pow(neg,non-integral)
67  *      25-- sinh(finite) overflow
68  *      26-- sqrt(negative)
69  *      27-- fmod(x,0)
70  *      28-- remainder(x,0)
71  *      29-- acosh(x<1)
72  *      30-- atanh(|x|>1)
73  *      31-- atanh(|x|=1)
74  *      32-- scalb overflow
75  *      33-- scalb underflow
76  *      34-- j0(|x|>X_TLOSS)
77  *      35-- y0(x>X_TLOSS)
78  *      36-- j1(|x|>X_TLOSS)
79  *      37-- y1(x>X_TLOSS)
80  *      38-- jn(|x|>X_TLOSS, n)
81  *      39-- yn(x>X_TLOSS, n)
82  *      40-- gamma(finite) overflow
83  *      41-- gamma(-integer)
84  *      42-- pow(NaN,0.0)
85  */
86 
87 
88 #ifdef __STDC__
__kernel_standard(double x,double y,int type)89         double __kernel_standard(double x, double y, int type)
90 #else
91         double __kernel_standard(x,y,type)
92         double x,y; int type;
93 #endif
94 {
95         struct exception exc;
96 #ifndef HUGE_VAL        /* this is the only routine that uses HUGE_VAL */
97 #define HUGE_VAL inf
98         double inf = 0.0;
99 
100         __HI(inf) = 0x7ff00000; /* set inf to infinite */
101 #endif
102 
103 #ifdef _USE_WRITE
104         (void) fflush(stdout);
105 #endif
106         exc.arg1 = x;
107         exc.arg2 = y;
108         switch(type) {
109             case 1:
110                 /* acos(|x|>1) */
111                 exc.type = DOMAIN;
112                 exc.name = "acos";
113                 exc.retval = zero;
114                 if (_LIB_VERSION == _POSIX_)
115                   errno = EDOM;
116                 else if (!matherr(&exc)) {
117                   if(_LIB_VERSION == _SVID_) {
118                     (void) WRITE2("acos: DOMAIN error\n", 19);
119                   }
120                   errno = EDOM;
121                 }
122                 break;
123             case 2:
124                 /* asin(|x|>1) */
125                 exc.type = DOMAIN;
126                 exc.name = "asin";
127                 exc.retval = zero;
128                 if(_LIB_VERSION == _POSIX_)
129                   errno = EDOM;
130                 else if (!matherr(&exc)) {
131                   if(_LIB_VERSION == _SVID_) {
132                         (void) WRITE2("asin: DOMAIN error\n", 19);
133                   }
134                   errno = EDOM;
135                 }
136                 break;
137             case 3:
138                 /* atan2(+-0,+-0) */
139                 exc.arg1 = y;
140                 exc.arg2 = x;
141                 exc.type = DOMAIN;
142                 exc.name = "atan2";
143                 exc.retval = zero;
144                 if(_LIB_VERSION == _POSIX_)
145                   errno = EDOM;
146                 else if (!matherr(&exc)) {
147                   if(_LIB_VERSION == _SVID_) {
148                         (void) WRITE2("atan2: DOMAIN error\n", 20);
149                       }
150                   errno = EDOM;
151                 }
152                 break;
153             case 4:
154                 /* hypot(finite,finite) overflow */
155                 exc.type = OVERFLOW;
156                 exc.name = "hypot";
157                 if (_LIB_VERSION == _SVID_)
158                   exc.retval = HUGE;
159                 else
160                   exc.retval = HUGE_VAL;
161                 if (_LIB_VERSION == _POSIX_)
162                   errno = ERANGE;
163                 else if (!matherr(&exc)) {
164                         errno = ERANGE;
165                 }
166                 break;
167             case 5:
168                 /* cosh(finite) overflow */
169                 exc.type = OVERFLOW;
170                 exc.name = "cosh";
171                 if (_LIB_VERSION == _SVID_)
172                   exc.retval = HUGE;
173                 else
174                   exc.retval = HUGE_VAL;
175                 if (_LIB_VERSION == _POSIX_)
176                   errno = ERANGE;
177                 else if (!matherr(&exc)) {
178                         errno = ERANGE;
179                 }
180                 break;
181             case 6:
182                 /* exp(finite) overflow */
183                 exc.type = OVERFLOW;
184                 exc.name = "exp";
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                 /* exp(finite) underflow */
197                 exc.type = UNDERFLOW;
198                 exc.name = "exp";
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                 /* y0(0) = -inf */
208                 exc.type = DOMAIN;      /* should be SING for IEEE */
209                 exc.name = "y0";
210                 if (_LIB_VERSION == _SVID_)
211                   exc.retval = -HUGE;
212                 else
213                   exc.retval = -HUGE_VAL;
214                 if (_LIB_VERSION == _POSIX_)
215                   errno = EDOM;
216                 else if (!matherr(&exc)) {
217                   if (_LIB_VERSION == _SVID_) {
218                         (void) WRITE2("y0: DOMAIN error\n", 17);
219                       }
220                   errno = EDOM;
221                 }
222                 break;
223             case 9:
224                 /* y0(x<0) = NaN */
225                 exc.type = DOMAIN;
226                 exc.name = "y0";
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                 /* y1(0) = -inf */
242                 exc.type = DOMAIN;      /* should be SING for IEEE */
243                 exc.name = "y1";
244                 if (_LIB_VERSION == _SVID_)
245                   exc.retval = -HUGE;
246                 else
247                   exc.retval = -HUGE_VAL;
248                 if (_LIB_VERSION == _POSIX_)
249                   errno = EDOM;
250                 else if (!matherr(&exc)) {
251                   if (_LIB_VERSION == _SVID_) {
252                         (void) WRITE2("y1: DOMAIN error\n", 17);
253                       }
254                   errno = EDOM;
255                 }
256                 break;
257             case 11:
258                 /* y1(x<0) = NaN */
259                 exc.type = DOMAIN;
260                 exc.name = "y1";
261                 if (_LIB_VERSION == _SVID_)
262                   exc.retval = -HUGE;
263                 else
264                   exc.retval = -HUGE_VAL;
265                 if (_LIB_VERSION == _POSIX_)
266                   errno = EDOM;
267                 else if (!matherr(&exc)) {
268                   if (_LIB_VERSION == _SVID_) {
269                         (void) WRITE2("y1: DOMAIN error\n", 17);
270                       }
271                   errno = EDOM;
272                 }
273                 break;
274             case 12:
275                 /* yn(n,0) = -inf */
276                 exc.type = DOMAIN;      /* should be SING for IEEE */
277                 exc.name = "yn";
278                 if (_LIB_VERSION == _SVID_)
279                   exc.retval = -HUGE;
280                 else
281                   exc.retval = -HUGE_VAL;
282                 if (_LIB_VERSION == _POSIX_)
283                   errno = EDOM;
284                 else if (!matherr(&exc)) {
285                   if (_LIB_VERSION == _SVID_) {
286                         (void) WRITE2("yn: DOMAIN error\n", 17);
287                       }
288                   errno = EDOM;
289                 }
290                 break;
291             case 13:
292                 /* yn(x<0) = NaN */
293                 exc.type = DOMAIN;
294                 exc.name = "yn";
295                 if (_LIB_VERSION == _SVID_)
296                   exc.retval = -HUGE;
297                 else
298                   exc.retval = -HUGE_VAL;
299                 if (_LIB_VERSION == _POSIX_)
300                   errno = EDOM;
301                 else if (!matherr(&exc)) {
302                   if (_LIB_VERSION == _SVID_) {
303                         (void) WRITE2("yn: DOMAIN error\n", 17);
304                       }
305                   errno = EDOM;
306                 }
307                 break;
308             case 14:
309                 /* lgamma(finite) overflow */
310                 exc.type = OVERFLOW;
311                 exc.name = "lgamma";
312                 if (_LIB_VERSION == _SVID_)
313                   exc.retval = HUGE;
314                 else
315                   exc.retval = HUGE_VAL;
316                 if (_LIB_VERSION == _POSIX_)
317                         errno = ERANGE;
318                 else if (!matherr(&exc)) {
319                         errno = ERANGE;
320                 }
321                 break;
322             case 15:
323                 /* lgamma(-integer) or lgamma(0) */
324                 exc.type = SING;
325                 exc.name = "lgamma";
326                 if (_LIB_VERSION == _SVID_)
327                   exc.retval = HUGE;
328                 else
329                   exc.retval = HUGE_VAL;
330                 if (_LIB_VERSION == _POSIX_)
331                   errno = EDOM;
332                 else if (!matherr(&exc)) {
333                   if (_LIB_VERSION == _SVID_) {
334                         (void) WRITE2("lgamma: SING error\n", 19);
335                       }
336                   errno = EDOM;
337                 }
338                 break;
339             case 16:
340                 /* log(0) */
341                 exc.type = SING;
342                 exc.name = "log";
343                 if (_LIB_VERSION == _SVID_)
344                   exc.retval = -HUGE;
345                 else
346                   exc.retval = -HUGE_VAL;
347                 if (_LIB_VERSION == _POSIX_)
348                   errno = ERANGE;
349                 else if (!matherr(&exc)) {
350                   if (_LIB_VERSION == _SVID_) {
351                         (void) WRITE2("log: SING error\n", 16);
352                       }
353                   errno = EDOM;
354                 }
355                 break;
356             case 17:
357                 /* log(x<0) */
358                 exc.type = DOMAIN;
359                 exc.name = "log";
360                 if (_LIB_VERSION == _SVID_)
361                   exc.retval = -HUGE;
362                 else
363                   exc.retval = -HUGE_VAL;
364                 if (_LIB_VERSION == _POSIX_)
365                   errno = EDOM;
366                 else if (!matherr(&exc)) {
367                   if (_LIB_VERSION == _SVID_) {
368                         (void) WRITE2("log: DOMAIN error\n", 18);
369                       }
370                   errno = EDOM;
371                 }
372                 break;
373             case 18:
374                 /* log10(0) */
375                 exc.type = SING;
376                 exc.name = "log10";
377                 if (_LIB_VERSION == _SVID_)
378                   exc.retval = -HUGE;
379                 else
380                   exc.retval = -HUGE_VAL;
381                 if (_LIB_VERSION == _POSIX_)
382                   errno = ERANGE;
383                 else if (!matherr(&exc)) {
384                   if (_LIB_VERSION == _SVID_) {
385                         (void) WRITE2("log10: SING error\n", 18);
386                       }
387                   errno = EDOM;
388                 }
389                 break;
390             case 19:
391                 /* log10(x<0) */
392                 exc.type = DOMAIN;
393                 exc.name = "log10";
394                 if (_LIB_VERSION == _SVID_)
395                   exc.retval = -HUGE;
396                 else
397                   exc.retval = -HUGE_VAL;
398                 if (_LIB_VERSION == _POSIX_)
399                   errno = EDOM;
400                 else if (!matherr(&exc)) {
401                   if (_LIB_VERSION == _SVID_) {
402                         (void) WRITE2("log10: DOMAIN error\n", 20);
403                       }
404                   errno = EDOM;
405                 }
406                 break;
407             case 20:
408                 /* pow(0.0,0.0) */
409                 /* error only if _LIB_VERSION == _SVID_ */
410                 exc.type = DOMAIN;
411                 exc.name = "pow";
412                 exc.retval = zero;
413                 if (_LIB_VERSION != _SVID_) exc.retval = 1.0;
414                 else if (!matherr(&exc)) {
415                         (void) WRITE2("pow(0,0): DOMAIN error\n", 23);
416                         errno = EDOM;
417                 }
418                 break;
419             case 21:
420                 /* pow(x,y) overflow */
421                 exc.type = OVERFLOW;
422                 exc.name = "pow";
423                 if (_LIB_VERSION == _SVID_) {
424                   exc.retval = HUGE;
425                   y *= 0.5;
426                   if(x<zero&&rint(y)!=y) exc.retval = -HUGE;
427                 } else {
428                   exc.retval = HUGE_VAL;
429                   y *= 0.5;
430                   if(x<zero&&rint(y)!=y) exc.retval = -HUGE_VAL;
431                 }
432                 if (_LIB_VERSION == _POSIX_)
433                   errno = ERANGE;
434                 else if (!matherr(&exc)) {
435                         errno = ERANGE;
436                 }
437                 break;
438             case 22:
439                 /* pow(x,y) underflow */
440                 exc.type = UNDERFLOW;
441                 exc.name = "pow";
442                 exc.retval =  zero;
443                 if (_LIB_VERSION == _POSIX_)
444                   errno = ERANGE;
445                 else if (!matherr(&exc)) {
446                         errno = ERANGE;
447                 }
448                 break;
449             case 23:
450                 /* 0**neg */
451                 exc.type = DOMAIN;
452                 exc.name = "pow";
453                 if (_LIB_VERSION == _SVID_)
454                   exc.retval = zero;
455                 else
456                   exc.retval = -HUGE_VAL;
457                 if (_LIB_VERSION == _POSIX_)
458                   errno = EDOM;
459                 else if (!matherr(&exc)) {
460                   if (_LIB_VERSION == _SVID_) {
461                         (void) WRITE2("pow(0,neg): DOMAIN error\n", 25);
462                       }
463                   errno = EDOM;
464                 }
465                 break;
466             case 24:
467                 /* neg**non-integral */
468                 exc.type = DOMAIN;
469                 exc.name = "pow";
470                 if (_LIB_VERSION == _SVID_)
471                     exc.retval = zero;
472                 else
473                     exc.retval = zero/zero;     /* X/Open allow NaN */
474                 if (_LIB_VERSION == _POSIX_)
475                    errno = EDOM;
476                 else if (!matherr(&exc)) {
477                   if (_LIB_VERSION == _SVID_) {
478                         (void) WRITE2("neg**non-integral: DOMAIN error\n", 32);
479                       }
480                   errno = EDOM;
481                 }
482                 break;
483             case 25:
484                 /* sinh(finite) overflow */
485                 exc.type = OVERFLOW;
486                 exc.name = "sinh";
487                 if (_LIB_VERSION == _SVID_)
488                   exc.retval = ( (x>zero) ? HUGE : -HUGE);
489                 else
490                   exc.retval = ( (x>zero) ? HUGE_VAL : -HUGE_VAL);
491                 if (_LIB_VERSION == _POSIX_)
492                   errno = ERANGE;
493                 else if (!matherr(&exc)) {
494                         errno = ERANGE;
495                 }
496                 break;
497             case 26:
498                 /* sqrt(x<0) */
499                 exc.type = DOMAIN;
500                 exc.name = "sqrt";
501                 if (_LIB_VERSION == _SVID_)
502                   exc.retval = zero;
503                 else
504                   exc.retval = zero/zero;
505                 if (_LIB_VERSION == _POSIX_)
506                   errno = EDOM;
507                 else if (!matherr(&exc)) {
508                   if (_LIB_VERSION == _SVID_) {
509                         (void) WRITE2("sqrt: DOMAIN error\n", 19);
510                       }
511                   errno = EDOM;
512                 }
513                 break;
514             case 27:
515                 /* fmod(x,0) */
516                 exc.type = DOMAIN;
517                 exc.name = "fmod";
518                 if (_LIB_VERSION == _SVID_)
519                     exc.retval = x;
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("fmod:  DOMAIN error\n", 20);
527                   }
528                   errno = EDOM;
529                 }
530                 break;
531             case 28:
532                 /* remainder(x,0) */
533                 exc.type = DOMAIN;
534                 exc.name = "remainder";
535                 exc.retval = zero/zero;
536                 if (_LIB_VERSION == _POSIX_)
537                   errno = EDOM;
538                 else if (!matherr(&exc)) {
539                   if (_LIB_VERSION == _SVID_) {
540                     (void) WRITE2("remainder: DOMAIN error\n", 24);
541                   }
542                   errno = EDOM;
543                 }
544                 break;
545             case 29:
546                 /* acosh(x<1) */
547                 exc.type = DOMAIN;
548                 exc.name = "acosh";
549                 exc.retval = zero/zero;
550                 if (_LIB_VERSION == _POSIX_)
551                   errno = EDOM;
552                 else if (!matherr(&exc)) {
553                   if (_LIB_VERSION == _SVID_) {
554                     (void) WRITE2("acosh: DOMAIN error\n", 20);
555                   }
556                   errno = EDOM;
557                 }
558                 break;
559             case 30:
560                 /* atanh(|x|>1) */
561                 exc.type = DOMAIN;
562                 exc.name = "atanh";
563                 exc.retval = zero/zero;
564                 if (_LIB_VERSION == _POSIX_)
565                   errno = EDOM;
566                 else if (!matherr(&exc)) {
567                   if (_LIB_VERSION == _SVID_) {
568                     (void) WRITE2("atanh: DOMAIN error\n", 20);
569                   }
570                   errno = EDOM;
571                 }
572                 break;
573             case 31:
574                 /* atanh(|x|=1) */
575                 exc.type = SING;
576                 exc.name = "atanh";
577                 exc.retval = x/zero;    /* sign(x)*inf */
578                 if (_LIB_VERSION == _POSIX_)
579                   errno = EDOM;
580                 else if (!matherr(&exc)) {
581                   if (_LIB_VERSION == _SVID_) {
582                     (void) WRITE2("atanh: SING error\n", 18);
583                   }
584                   errno = EDOM;
585                 }
586                 break;
587             case 32:
588                 /* scalb overflow; SVID also returns +-HUGE_VAL */
589                 exc.type = OVERFLOW;
590                 exc.name = "scalb";
591                 exc.retval = x > zero ? HUGE_VAL : -HUGE_VAL;
592                 if (_LIB_VERSION == _POSIX_)
593                   errno = ERANGE;
594                 else if (!matherr(&exc)) {
595                         errno = ERANGE;
596                 }
597                 break;
598             case 33:
599                 /* scalb underflow */
600                 exc.type = UNDERFLOW;
601                 exc.name = "scalb";
602                 exc.retval = copysign(zero,x);
603                 if (_LIB_VERSION == _POSIX_)
604                   errno = ERANGE;
605                 else if (!matherr(&exc)) {
606                         errno = ERANGE;
607                 }
608                 break;
609             case 34:
610                 /* j0(|x|>X_TLOSS) */
611                 exc.type = TLOSS;
612                 exc.name = "j0";
613                 exc.retval = zero;
614                 if (_LIB_VERSION == _POSIX_)
615                         errno = ERANGE;
616                 else if (!matherr(&exc)) {
617                         if (_LIB_VERSION == _SVID_) {
618                                 (void) WRITE2(exc.name, 2);
619                                 (void) WRITE2(": TLOSS error\n", 14);
620                         }
621                         errno = ERANGE;
622                 }
623                 break;
624             case 35:
625                 /* y0(x>X_TLOSS) */
626                 exc.type = TLOSS;
627                 exc.name = "y0";
628                 exc.retval = zero;
629                 if (_LIB_VERSION == _POSIX_)
630                         errno = ERANGE;
631                 else if (!matherr(&exc)) {
632                         if (_LIB_VERSION == _SVID_) {
633                                 (void) WRITE2(exc.name, 2);
634                                 (void) WRITE2(": TLOSS error\n", 14);
635                         }
636                         errno = ERANGE;
637                 }
638                 break;
639             case 36:
640                 /* j1(|x|>X_TLOSS) */
641                 exc.type = TLOSS;
642                 exc.name = "j1";
643                 exc.retval = zero;
644                 if (_LIB_VERSION == _POSIX_)
645                         errno = ERANGE;
646                 else if (!matherr(&exc)) {
647                         if (_LIB_VERSION == _SVID_) {
648                                 (void) WRITE2(exc.name, 2);
649                                 (void) WRITE2(": TLOSS error\n", 14);
650                         }
651                         errno = ERANGE;
652                 }
653                 break;
654             case 37:
655                 /* y1(x>X_TLOSS) */
656                 exc.type = TLOSS;
657                 exc.name = "y1";
658                 exc.retval = zero;
659                 if (_LIB_VERSION == _POSIX_)
660                         errno = ERANGE;
661                 else if (!matherr(&exc)) {
662                         if (_LIB_VERSION == _SVID_) {
663                                 (void) WRITE2(exc.name, 2);
664                                 (void) WRITE2(": TLOSS error\n", 14);
665                         }
666                         errno = ERANGE;
667                 }
668                 break;
669             case 38:
670                 /* jn(|x|>X_TLOSS) */
671                 exc.type = TLOSS;
672                 exc.name = "jn";
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 39:
685                 /* yn(x>X_TLOSS) */
686                 exc.type = TLOSS;
687                 exc.name = "yn";
688                 exc.retval = zero;
689                 if (_LIB_VERSION == _POSIX_)
690                         errno = ERANGE;
691                 else if (!matherr(&exc)) {
692                         if (_LIB_VERSION == _SVID_) {
693                                 (void) WRITE2(exc.name, 2);
694                                 (void) WRITE2(": TLOSS error\n", 14);
695                         }
696                         errno = ERANGE;
697                 }
698                 break;
699             case 40:
700                 /* gamma(finite) overflow */
701                 exc.type = OVERFLOW;
702                 exc.name = "gamma";
703                 if (_LIB_VERSION == _SVID_)
704                   exc.retval = HUGE;
705                 else
706                   exc.retval = HUGE_VAL;
707                 if (_LIB_VERSION == _POSIX_)
708                   errno = ERANGE;
709                 else if (!matherr(&exc)) {
710                   errno = ERANGE;
711                 }
712                 break;
713             case 41:
714                 /* gamma(-integer) or gamma(0) */
715                 exc.type = SING;
716                 exc.name = "gamma";
717                 if (_LIB_VERSION == _SVID_)
718                   exc.retval = HUGE;
719                 else
720                   exc.retval = HUGE_VAL;
721                 if (_LIB_VERSION == _POSIX_)
722                   errno = EDOM;
723                 else if (!matherr(&exc)) {
724                   if (_LIB_VERSION == _SVID_) {
725                         (void) WRITE2("gamma: SING error\n", 18);
726                       }
727                   errno = EDOM;
728                 }
729                 break;
730             case 42:
731                 /* pow(NaN,0.0) */
732                 /* error only if _LIB_VERSION == _SVID_ & _XOPEN_ */
733                 exc.type = DOMAIN;
734                 exc.name = "pow";
735                 exc.retval = x;
736                 if (_LIB_VERSION == _IEEE_ ||
737                     _LIB_VERSION == _POSIX_) exc.retval = 1.0;
738                 else if (!matherr(&exc)) {
739                         errno = EDOM;
740                 }
741                 break;
742         }
743         return exc.retval;
744 }
745