]> git.karo-electronics.de Git - karo-tx-redboot.git/blob - packages/language/c/libm/v2_0/src/misc/standard.c
Initial revision
[karo-tx-redboot.git] / packages / language / c / libm / v2_0 / src / misc / standard.c
1 //===========================================================================
2 //
3 //      signgam.cxx
4 //
5 //      Support sign of the gamma*() functions in Math library
6 //
7 //===========================================================================
8 //####ECOSGPLCOPYRIGHTBEGIN####
9 // -------------------------------------------
10 // This file is part of eCos, the Embedded Configurable Operating System.
11 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
12 //
13 // eCos is free software; you can redistribute it and/or modify it under
14 // the terms of the GNU General Public License as published by the Free
15 // Software Foundation; either version 2 or (at your option) any later version.
16 //
17 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
18 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
20 // for more details.
21 //
22 // You should have received a copy of the GNU General Public License along
23 // with eCos; if not, write to the Free Software Foundation, Inc.,
24 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
25 //
26 // As a special exception, if other files instantiate templates or use macros
27 // or inline functions from this file, or you compile this file and link it
28 // with other works to produce a work based on this file, this file does not
29 // by itself cause the resulting work to be covered by the GNU General Public
30 // License. However the source code for this file must still be made available
31 // in accordance with section (3) of the GNU General Public License.
32 //
33 // This exception does not invalidate any other reasons why a work based on
34 // this file might be covered by the GNU General Public License.
35 //
36 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
37 // at http://sources.redhat.com/ecos/ecos-license/
38 // -------------------------------------------
39 //####ECOSGPLCOPYRIGHTEND####
40 //===========================================================================
41 //#####DESCRIPTIONBEGIN####
42 //
43 // Author(s):   jlarmour
44 // Contributors:  jlarmour
45 // Date:        1998-02-13
46 // Purpose:     
47 // Description: Contains the accessor functions to get and set the stored sign
48 //              of the gamma*() functions in the math library
49 // Usage:       
50 //
51 //####DESCRIPTIONEND####
52 //
53 //===========================================================================
54
55 /* @(#)k_standard.c 1.3 95/01/18 */
56 /*
57  * ====================================================
58  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
59  *
60  * Developed at SunSoft, a Sun Microsystems, Inc. business.
61  * Permission to use, copy, modify, and distribute this
62  * software is freely granted, provided that this notice 
63  * is preserved.
64  * ====================================================
65  *
66  */
67
68 // CONFIGURATION
69
70 #include <pkgconf/libm.h>   // Configuration header
71
72 // Include the Math library?
73 #ifdef CYGPKG_LIBM
74
75 // INCLUDES
76
77 #include <cyg/infra/cyg_type.h>    // Common type definitions and support
78 #include <cyg/infra/cyg_trac.h>    // Tracing macros
79
80 #include <math.h>                  // Main header for math library
81 #include "mathincl/fdlibm.h"       // Internal header for math library
82
83 #include <cyg/error/codes.h>       // standard error codes
84
85 #ifndef CYGSEM_LIBM_COMPAT_IEEE_ONLY
86 #include <errno.h>
87 #else
88 static int errno; // this whole file won't be used if we're IEEE only, but
89                   // doing this keeps the compiler happy
90 #endif
91
92 #ifdef CYGSEM_LIBM_USE_STDERR
93
94 #include <stdio.h>
95 #define WRITE2(u,v)     fputs(u, stderr)
96
97 #else
98
99 #define WRITE2(u,v)     0
100
101 #endif // ifdef CYGSEM_LIBM_USE_STDERR
102
103
104 // GLOBALS
105
106 static const double zero = 0.0;
107
108 // FUNCTIONS
109
110 /* 
111  * Standard conformance (non-IEEE) on exception cases.
112  * Mapping:
113  *      1 -- acos(|x|>1)
114  *      2 -- asin(|x|>1)
115  *      3 -- atan2(+-0,+-0)
116  *      4 -- hypot overflow
117  *      5 -- cosh overflow
118  *      6 -- exp overflow
119  *      7 -- exp underflow
120  *      8 -- y0(0)
121  *      9 -- y0(-ve)
122  *      10-- y1(0)
123  *      11-- y1(-ve)
124  *      12-- yn(0)
125  *      13-- yn(-ve)
126  *      14-- lgamma(finite) overflow
127  *      15-- lgamma(-integer)
128  *      16-- log(0)
129  *      17-- log(x<0)
130  *      18-- log10(0)
131  *      19-- log10(x<0)
132  *      20-- pow(0.0,0.0)
133  *      21-- pow(x,y) overflow
134  *      22-- pow(x,y) underflow
135  *      23-- pow(0,negative) 
136  *      24-- pow(neg,non-integral)
137  *      25-- sinh(finite) overflow
138  *      26-- sqrt(negative)
139  *      27-- fmod(x,0)
140  *      28-- remainder(x,0)
141  *      29-- acosh(x<1)
142  *      30-- atanh(|x|>1)
143  *      31-- atanh(|x|=1)
144  *      32-- scalb overflow
145  *      33-- scalb underflow
146  *      34-- j0(|x|>X_TLOSS)
147  *      35-- y0(x>X_TLOSS)
148  *      36-- j1(|x|>X_TLOSS)
149  *      37-- y1(x>X_TLOSS)
150  *      38-- jn(|x|>X_TLOSS, n)
151  *      39-- yn(x>X_TLOSS, n)
152  *      40-- gamma(finite) overflow
153  *      41-- gamma(-integer)
154  *      42-- pow(NaN,0.0)
155  *      43-- ldexp overflow
156  *      44-- ldexp underflow
157  */
158
159
160 double
161 __kernel_standard(double x, double y, int type) 
162 {
163         struct exception exc;
164
165 #ifdef CYGSEM_LIBM_USE_STDERR
166         (void) fflush(stdout);
167 #endif
168         exc.arg1 = x;
169         exc.arg2 = y;
170         switch(type) {
171             case 1:
172                 /* acos(|x|>1) */
173                 exc.type = DOMAIN;
174                 exc.name = "acos";
175                 exc.retval = zero;
176                 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_POSIX)
177                   errno = EDOM;
178                 else if (!matherr(&exc)) {
179                   if(cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID) {
180                     (void) WRITE2("acos: DOMAIN error\n", 19);
181                   }
182                   errno = EDOM;
183                 }
184                 break;
185             case 2:
186                 /* asin(|x|>1) */
187                 exc.type = DOMAIN;
188                 exc.name = "asin";
189                 exc.retval = zero;
190                 if(cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_POSIX)
191                   errno = EDOM;
192                 else if (!matherr(&exc)) {
193                   if(cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID) {
194                         (void) WRITE2("asin: DOMAIN error\n", 19);
195                   }
196                   errno = EDOM;
197                 }
198                 break;
199             case 3:
200                 /* atan2(+-0,+-0) */
201                 exc.arg1 = y;
202                 exc.arg2 = x;
203                 exc.type = DOMAIN;
204                 exc.name = "atan2";
205                 exc.retval = zero;
206                 if(cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_POSIX)
207                   errno = EDOM;
208                 else if (!matherr(&exc)) {
209                   if(cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID) {
210                         (void) WRITE2("atan2: DOMAIN error\n", 20);
211                       }
212                   errno = EDOM;
213                 }
214                 break;
215             case 4:
216                 /* hypot(finite,finite) overflow */
217                 exc.type = OVERFLOW;
218                 exc.name = "hypot";
219                 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID)
220                   exc.retval = HUGE;
221                 else
222                   exc.retval = HUGE_VAL;
223                 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_POSIX)
224                   errno = ERANGE;
225                 else if (!matherr(&exc)) {
226                         errno = ERANGE;
227                 }
228                 break;
229             case 5:
230                 /* cosh(finite) overflow */
231                 exc.type = OVERFLOW;
232                 exc.name = "cosh";
233                 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID)
234                   exc.retval = HUGE;
235                 else
236                   exc.retval = HUGE_VAL;
237                 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_POSIX)
238                   errno = ERANGE;
239                 else if (!matherr(&exc)) {
240                         errno = ERANGE;
241                 }
242                 break;
243             case 6:
244                 /* exp(finite) overflow */
245                 exc.type = OVERFLOW;
246                 exc.name = "exp";
247                 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID)
248                   exc.retval = HUGE;
249                 else
250                   exc.retval = HUGE_VAL;
251                 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_POSIX)
252                   errno = ERANGE;
253                 else if (!matherr(&exc)) {
254                         errno = ERANGE;
255                 }
256                 break;
257             case 7:
258                 /* exp(finite) underflow */
259                 exc.type = UNDERFLOW;
260                 exc.name = "exp";
261                 exc.retval = zero;
262                 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_POSIX)
263                   errno = ERANGE;
264                 else if (!matherr(&exc)) {
265                         errno = ERANGE;
266                 }
267                 break;
268             case 8:
269                 /* y0(0) = -inf */
270                 exc.type = DOMAIN;      /* should be SING for IEEE */
271                 exc.name = "y0";
272                 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID)
273                   exc.retval = -HUGE;
274                 else
275                   exc.retval = -HUGE_VAL;
276                 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_POSIX)
277                   errno = EDOM;
278                 else if (!matherr(&exc)) {
279                   if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID) {
280                         (void) WRITE2("y0: DOMAIN error\n", 17);
281                       }
282                   errno = EDOM;
283                 }
284                 break;
285             case 9:
286                 /* y0(x<0) = NaN */
287                 exc.type = DOMAIN;
288                 exc.name = "y0";
289                 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID)
290                   exc.retval = -HUGE;
291                 else
292                   exc.retval = -HUGE_VAL;
293                 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_POSIX)
294                   errno = EDOM;
295                 else if (!matherr(&exc)) {
296                   if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID) {
297                         (void) WRITE2("y0: DOMAIN error\n", 17);
298                       }
299                   errno = EDOM;
300                 }
301                 break;
302             case 10:
303                 /* y1(0) = -inf */
304                 exc.type = DOMAIN;      /* should be SING for IEEE */
305                 exc.name = "y1";
306                 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID)
307                   exc.retval = -HUGE;
308                 else
309                   exc.retval = -HUGE_VAL;
310                 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_POSIX)
311                   errno = EDOM;
312                 else if (!matherr(&exc)) {
313                   if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID) {
314                         (void) WRITE2("y1: DOMAIN error\n", 17);
315                       }
316                   errno = EDOM;
317                 }
318                 break;
319             case 11:
320                 /* y1(x<0) = NaN */
321                 exc.type = DOMAIN;
322                 exc.name = "y1";
323                 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID)
324                   exc.retval = -HUGE;
325                 else
326                   exc.retval = -HUGE_VAL;
327                 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_POSIX)
328                   errno = EDOM;
329                 else if (!matherr(&exc)) {
330                   if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID) {
331                         (void) WRITE2("y1: DOMAIN error\n", 17);
332                       }
333                   errno = EDOM;
334                 }
335                 break;
336             case 12:
337                 /* yn(n,0) = -inf */
338                 exc.type = DOMAIN;      /* should be SING for IEEE */
339                 exc.name = "yn";
340                 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID)
341                   exc.retval = -HUGE;
342                 else
343                   exc.retval = -HUGE_VAL;
344                 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_POSIX)
345                   errno = EDOM;
346                 else if (!matherr(&exc)) {
347                   if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID) {
348                         (void) WRITE2("yn: DOMAIN error\n", 17);
349                       }
350                   errno = EDOM;
351                 }
352                 break;
353             case 13:
354                 /* yn(x<0) = NaN */
355                 exc.type = DOMAIN;
356                 exc.name = "yn";
357                 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID)
358                   exc.retval = -HUGE;
359                 else
360                   exc.retval = -HUGE_VAL;
361                 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_POSIX)
362                   errno = EDOM;
363                 else if (!matherr(&exc)) {
364                   if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID) {
365                         (void) WRITE2("yn: DOMAIN error\n", 17);
366                       }
367                   errno = EDOM;
368                 }
369                 break;
370             case 14:
371                 /* lgamma(finite) overflow */
372                 exc.type = OVERFLOW;
373                 exc.name = "lgamma";
374                 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID)
375                   exc.retval = HUGE;
376                 else
377                   exc.retval = HUGE_VAL;
378                 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_POSIX)
379                         errno = ERANGE;
380                 else if (!matherr(&exc)) {
381                         errno = ERANGE;
382                 }
383                 break;
384             case 15:
385                 /* lgamma(-integer) or lgamma(0) */
386                 exc.type = SING;
387                 exc.name = "lgamma";
388                 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID)
389                   exc.retval = HUGE;
390                 else
391                   exc.retval = HUGE_VAL;
392                 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_POSIX)
393                   errno = EDOM;
394                 else if (!matherr(&exc)) {
395                   if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID) {
396                         (void) WRITE2("lgamma: SING error\n", 19);
397                       }
398                   errno = EDOM;
399                 }
400                 break;
401             case 16:
402                 /* log(0) */
403                 exc.type = SING;
404                 exc.name = "log";
405                 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID)
406                   exc.retval = -HUGE;
407                 else
408                   exc.retval = -HUGE_VAL;
409                 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_POSIX)
410                   errno = ERANGE;
411                 else if (!matherr(&exc)) {
412                   if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID) {
413                         (void) WRITE2("log: SING error\n", 16);
414                       }
415                   errno = EDOM;
416                 }
417                 break;
418             case 17:
419                 /* log(x<0) */
420                 exc.type = DOMAIN;
421                 exc.name = "log";
422                 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID)
423                   exc.retval = -HUGE;
424                 else
425                   exc.retval = -HUGE_VAL;
426                 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_POSIX)
427                   errno = EDOM;
428                 else if (!matherr(&exc)) {
429                   if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID) {
430                         (void) WRITE2("log: DOMAIN error\n", 18);
431                       }
432                   errno = EDOM;
433                 }
434                 break;
435             case 18:
436                 /* log10(0) */
437                 exc.type = SING;
438                 exc.name = "log10";
439                 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID)
440                   exc.retval = -HUGE;
441                 else
442                   exc.retval = -HUGE_VAL;
443                 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_POSIX)
444                   errno = ERANGE;
445                 else if (!matherr(&exc)) {
446                   if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID) {
447                         (void) WRITE2("log10: SING error\n", 18);
448                       }
449                   errno = EDOM;
450                 }
451                 break;
452             case 19:
453                 /* log10(x<0) */
454                 exc.type = DOMAIN;
455                 exc.name = "log10";
456                 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID)
457                   exc.retval = -HUGE;
458                 else
459                   exc.retval = -HUGE_VAL;
460                 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_POSIX)
461                   errno = EDOM;
462                 else if (!matherr(&exc)) {
463                   if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID) {
464                         (void) WRITE2("log10: DOMAIN error\n", 20);
465                       }
466                   errno = EDOM;
467                 }
468                 break;
469             case 20:
470                 /* pow(0.0,0.0) */
471                 /* error only if cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID */
472                 exc.type = DOMAIN;
473                 exc.name = "pow";
474                 exc.retval = zero;
475                 if (cyg_libm_get_compat_mode() != CYGNUM_LIBM_COMPAT_SVID) exc.retval = 1.0;
476                 else if (!matherr(&exc)) {
477                         (void) WRITE2("pow(0,0): DOMAIN error\n", 23);
478                         errno = EDOM;
479                 }
480                 break;
481             case 21:
482                 /* pow(x,y) overflow */
483                 exc.type = OVERFLOW;
484                 exc.name = "pow";
485                 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID) {
486                   exc.retval = HUGE;
487                   y *= 0.5;
488                   if(x<zero&&rint(y)!=y) exc.retval = -HUGE;
489                 } else {
490                   exc.retval = HUGE_VAL;
491                   y *= 0.5;
492                   if(x<zero&&rint(y)!=y) exc.retval = -HUGE_VAL;
493                 }
494                 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_POSIX)
495                   errno = ERANGE;
496                 else if (!matherr(&exc)) {
497                         errno = ERANGE;
498                 }
499                 break;
500             case 22:
501                 /* pow(x,y) underflow */
502                 exc.type = UNDERFLOW;
503                 exc.name = "pow";
504                 exc.retval =  zero;
505                 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_POSIX)
506                   errno = ERANGE;
507                 else if (!matherr(&exc)) {
508                         errno = ERANGE;
509                 }
510                 break;
511             case 23:
512                 /* 0**neg */
513                 exc.type = DOMAIN;
514                 exc.name = "pow";
515                 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID) 
516                   exc.retval = zero;
517                 else
518                   exc.retval = -HUGE_VAL;
519                 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_POSIX)
520                   errno = EDOM;
521                 else if (!matherr(&exc)) {
522                   if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID) {
523                         (void) WRITE2("pow(0,neg): DOMAIN error\n", 25);
524                       }
525                   errno = EDOM;
526                 }
527                 break;
528             case 24:
529                 /* neg**non-integral */
530                 exc.type = DOMAIN;
531                 exc.name = "pow";
532                 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID) 
533                     exc.retval = zero;
534                 else 
535                     exc.retval = zero/zero;     /* X/Open allow NaN */
536                 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_POSIX) 
537                    errno = EDOM;
538                 else if (!matherr(&exc)) {
539                   if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID) {
540                         (void) WRITE2("neg**non-integral: DOMAIN error\n", 32);
541                       }
542                   errno = EDOM;
543                 }
544                 break;
545             case 25:
546                 /* sinh(finite) overflow */
547                 exc.type = OVERFLOW;
548                 exc.name = "sinh";
549                 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID)
550                   exc.retval = ( (x>zero) ? HUGE : -HUGE);
551                 else
552                   exc.retval = ( (x>zero) ? HUGE_VAL : -HUGE_VAL);
553                 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_POSIX)
554                   errno = ERANGE;
555                 else if (!matherr(&exc)) {
556                         errno = ERANGE;
557                 }
558                 break;
559             case 26:
560                 /* sqrt(x<0) */
561                 exc.type = DOMAIN;
562                 exc.name = "sqrt";
563                 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID)
564                   exc.retval = zero;
565                 else
566                   exc.retval = zero/zero;
567                 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_POSIX)
568                   errno = EDOM;
569                 else if (!matherr(&exc)) {
570                   if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID) {
571                         (void) WRITE2("sqrt: DOMAIN error\n", 19);
572                       }
573                   errno = EDOM;
574                 }
575                 break;
576             case 27:
577                 /* fmod(x,0) */
578                 exc.type = DOMAIN;
579                 exc.name = "fmod";
580                 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID)
581                     exc.retval = x;
582                 else
583                     exc.retval = zero/zero;
584                 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_POSIX)
585                   errno = EDOM;
586                 else if (!matherr(&exc)) {
587                   if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID) {
588                     (void) WRITE2("fmod:  DOMAIN error\n", 20);
589                   }
590                   errno = EDOM;
591                 }
592                 break;
593             case 28:
594                 /* remainder(x,0) */
595                 exc.type = DOMAIN;
596                 exc.name = "remainder";
597                 exc.retval = zero/zero;
598                 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_POSIX)
599                   errno = EDOM;
600                 else if (!matherr(&exc)) {
601                   if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID) {
602                     (void) WRITE2("remainder: DOMAIN error\n", 24);
603                   }
604                   errno = EDOM;
605                 }
606                 break;
607             case 29:
608                 /* acosh(x<1) */
609                 exc.type = DOMAIN;
610                 exc.name = "acosh";
611                 exc.retval = zero/zero;
612                 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_POSIX)
613                   errno = EDOM;
614                 else if (!matherr(&exc)) {
615                   if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID) {
616                     (void) WRITE2("acosh: DOMAIN error\n", 20);
617                   }
618                   errno = EDOM;
619                 }
620                 break;
621             case 30:
622                 /* atanh(|x|>1) */
623                 exc.type = DOMAIN;
624                 exc.name = "atanh";
625                 exc.retval = zero/zero;
626                 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_POSIX)
627                   errno = EDOM;
628                 else if (!matherr(&exc)) {
629                   if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID) {
630                     (void) WRITE2("atanh: DOMAIN error\n", 20);
631                   }
632                   errno = EDOM;
633                 }
634                 break;
635             case 31:
636                 /* atanh(|x|=1) */
637                 exc.type = SING;
638                 exc.name = "atanh";
639                 exc.retval = x/zero;    /* sign(x)*inf */
640                 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_POSIX)
641                   errno = EDOM;
642                 else if (!matherr(&exc)) {
643                   if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID) {
644                     (void) WRITE2("atanh: SING error\n", 18);
645                   }
646                   errno = EDOM;
647                 }
648                 break;
649             case 32:
650                 /* scalb overflow; SVID also returns +-HUGE_VAL */
651                 exc.type = OVERFLOW;
652                 exc.name = "scalb";
653                 exc.retval = x > zero ? HUGE_VAL : -HUGE_VAL;
654                 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_POSIX)
655                   errno = ERANGE;
656                 else if (!matherr(&exc)) {
657                         errno = ERANGE;
658                 }
659                 break;
660             case 33:
661                 /* scalb underflow */
662                 exc.type = UNDERFLOW;
663                 exc.name = "scalb";
664                 exc.retval = copysign(zero,x);
665                 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_POSIX)
666                   errno = ERANGE;
667                 else if (!matherr(&exc)) {
668                         errno = ERANGE;
669                 }
670                 break;
671             case 34:
672                 /* j0(|x|>X_TLOSS) */
673                 exc.type = TLOSS;
674                 exc.name = "j0";
675                 exc.retval = zero;
676                 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_POSIX)
677                         errno = ERANGE;
678                 else if (!matherr(&exc)) {
679                         if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID) {
680                                 (void) WRITE2(exc.name, 2);
681                                 (void) WRITE2(": TLOSS error\n", 14);
682                         }
683                         errno = ERANGE;
684                 }        
685                 break;
686             case 35:
687                 /* y0(x>X_TLOSS) */
688                 exc.type = TLOSS;
689                 exc.name = "y0";
690                 exc.retval = zero;
691                 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_POSIX)
692                         errno = ERANGE;
693                 else if (!matherr(&exc)) {
694                         if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID) {
695                                 (void) WRITE2(exc.name, 2);
696                                 (void) WRITE2(": TLOSS error\n", 14);
697                         }
698                         errno = ERANGE;
699                 }        
700                 break;
701             case 36:
702                 /* j1(|x|>X_TLOSS) */
703                 exc.type = TLOSS;
704                 exc.name = "j1";
705                 exc.retval = zero;
706                 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_POSIX)
707                         errno = ERANGE;
708                 else if (!matherr(&exc)) {
709                         if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID) {
710                                 (void) WRITE2(exc.name, 2);
711                                 (void) WRITE2(": TLOSS error\n", 14);
712                         }
713                         errno = ERANGE;
714                 }        
715                 break;
716             case 37:
717                 /* y1(x>X_TLOSS) */
718                 exc.type = TLOSS;
719                 exc.name = "y1";
720                 exc.retval = zero;
721                 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_POSIX)
722                         errno = ERANGE;
723                 else if (!matherr(&exc)) {
724                         if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID) {
725                                 (void) WRITE2(exc.name, 2);
726                                 (void) WRITE2(": TLOSS error\n", 14);
727                         }
728                         errno = ERANGE;
729                 }        
730                 break;
731             case 38:
732                 /* jn(|x|>X_TLOSS) */
733                 exc.type = TLOSS;
734                 exc.name = "jn";
735                 exc.retval = zero;
736                 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_POSIX)
737                         errno = ERANGE;
738                 else if (!matherr(&exc)) {
739                         if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID) {
740                                 (void) WRITE2(exc.name, 2);
741                                 (void) WRITE2(": TLOSS error\n", 14);
742                         }
743                         errno = ERANGE;
744                 }        
745                 break;
746             case 39:
747                 /* yn(x>X_TLOSS) */
748                 exc.type = TLOSS;
749                 exc.name = "yn";
750                 exc.retval = zero;
751                 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_POSIX)
752                         errno = ERANGE;
753                 else if (!matherr(&exc)) {
754                         if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID) {
755                                 (void) WRITE2(exc.name, 2);
756                                 (void) WRITE2(": TLOSS error\n", 14);
757                         }
758                         errno = ERANGE;
759                 }        
760                 break;
761             case 40:
762                 /* gamma(finite) overflow */
763                 exc.type = OVERFLOW;
764                 exc.name = "gamma";
765                 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID)
766                   exc.retval = HUGE;
767                 else
768                   exc.retval = HUGE_VAL;
769                 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_POSIX)
770                   errno = ERANGE;
771                 else if (!matherr(&exc)) {
772                   errno = ERANGE;
773                 }
774                 break;
775             case 41:
776                 /* gamma(-integer) or gamma(0) */
777                 exc.type = SING;
778                 exc.name = "gamma";
779                 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID)
780                   exc.retval = HUGE;
781                 else
782                   exc.retval = HUGE_VAL;
783                 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_POSIX)
784                   errno = EDOM;
785                 else if (!matherr(&exc)) {
786                   if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID) {
787                         (void) WRITE2("gamma: SING error\n", 18);
788                       }
789                   errno = EDOM;
790                 }
791                 break;
792             case 42:
793                 /* pow(NaN,0.0) */
794                 /* error only if cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID & CYGNUM_LIBM_COMPAT_XOPEN */
795                 exc.type = DOMAIN;
796                 exc.name = "pow";
797                 exc.retval = x;
798                 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_IEEE ||
799                     cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_POSIX) exc.retval = 1.0;
800                 else if (!matherr(&exc)) {
801                         errno = EDOM;
802                 }
803                 break;
804             case 43:
805                 /* ldexp overflow; SVID also returns +-HUGE_VAL */
806                 exc.type = OVERFLOW;
807                 exc.name = "ldexp";
808                 exc.retval = x > zero ? HUGE_VAL : -HUGE_VAL;
809                 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_POSIX)
810                   errno = ERANGE;
811                 else if (!matherr(&exc)) {
812                         errno = ERANGE;
813                 }
814                 break;
815             case 44:
816                 /* ldexp underflow */
817                 exc.type = UNDERFLOW;
818                 exc.name = "ldexp";
819                 exc.retval = copysign(zero,x);
820                 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_POSIX)
821                   errno = ERANGE;
822                 else if (!matherr(&exc)) {
823                         errno = ERANGE;
824                 }
825                 break;
826         }
827         return exc.retval; 
828 }
829
830 #endif // ifdef CYGPKG_LIBM
831
832 // EOF standard.c