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
38static 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__
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