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__
  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 }