1 /* @(#)k_standard.c 5.1 93/09/24 */
3 * ====================================================
4 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
6 * Developed at SunPro, a Sun Microsystems, Inc. business.
7 * Permission to use, copy, modify, and distribute this
8 * software is freely granted, provided that this notice
10 * ====================================================
13 #include <sys/cdefs.h>
14 #if defined(LIBM_SCCS) && !defined(lint)
15 __RCSID("$NetBSD: k_standard.c,v 1.20 2015/09/08 05:23:31 dholland Exp $");
19 #include "math_private.h"
23 #include <stdio.h> /* fputs(), stderr */
24 #define WRITE2(u,v) fputs(u, stderr)
25 #else /* !defined(_USE_WRITE) */
26 #include <unistd.h> /* write */
27 #define WRITE2(u,v) write(2, u, v)
29 #endif /* !defined(_USE_WRITE) */
31 static const double zero
= 0.0; /* used as const */
34 * Standard conformance (non-IEEE) on exception cases.
49 * 14-- lgamma(finite) overflow
50 * 15-- lgamma(-integer)
56 * 21-- pow(x,y) overflow
57 * 22-- pow(x,y) underflow
58 * 23-- pow(0,negative)
59 * 24-- pow(neg,non-integral)
60 * 25-- sinh(finite) overflow
68 * 33-- scalb underflow
69 * 34-- j0(|x|>X_TLOSS)
71 * 36-- j1(|x|>X_TLOSS)
73 * 38-- jn(|x|>X_TLOSS, n)
74 * 39-- yn(x>X_TLOSS, n)
75 * 40-- gamma(finite) overflow
76 * 41-- gamma(-integer)
84 __kernel_standard(double x
, double y
, int type
)
87 #ifndef HUGE_VAL /* this is the only routine that uses HUGE_VAL */
91 SET_HIGH_WORD(inf
,0x7ff00000); /* set inf to infinite */
95 (void) fflush(stdout
);
104 exc
.name
= type
< 100 ? "acos" : "acosf";
106 if (_LIB_VERSION
== _POSIX_
) {
107 exc
.retval
= zero
/zero
;
109 } else if (!matherr(&exc
)) {
110 if(_LIB_VERSION
== _SVID_
) {
111 (void) WRITE2("acos: DOMAIN error\n", 19);
120 exc
.name
= type
< 100 ? "asin" : "asinf";
122 if(_LIB_VERSION
== _POSIX_
) {
123 exc
.retval
= zero
/zero
;
125 } else if (!matherr(&exc
)) {
126 if(_LIB_VERSION
== _SVID_
) {
127 (void) WRITE2("asin: DOMAIN error\n", 19);
138 exc
.name
= type
< 100 ? "atan2" : "atan2f";
140 if(_LIB_VERSION
== _POSIX_
) {
141 exc
.retval
= copysign(signbit(y
) ? M_PI
: zero
, x
);
142 } else if (!matherr(&exc
)) {
143 if(_LIB_VERSION
== _SVID_
) {
144 (void) WRITE2("atan2: DOMAIN error\n", 20);
151 /* hypot(finite,finite) overflow */
153 exc
.name
= type
< 100 ? "hypot" : "hypotf";
154 if (_LIB_VERSION
== _SVID_
)
157 exc
.retval
= HUGE_VAL
;
158 if (_LIB_VERSION
== _POSIX_
)
160 else if (!matherr(&exc
)) {
166 /* cosh(finite) overflow */
168 exc
.name
= type
< 100 ? "cosh" : "coshf";
169 if (_LIB_VERSION
== _SVID_
)
172 exc
.retval
= HUGE_VAL
;
173 if (_LIB_VERSION
== _POSIX_
)
175 else if (!matherr(&exc
)) {
181 /* exp(finite) overflow */
183 exc
.name
= type
< 100 ? "exp" : "expf";
184 if (_LIB_VERSION
== _SVID_
)
187 exc
.retval
= HUGE_VAL
;
188 if (_LIB_VERSION
== _POSIX_
)
190 else if (!matherr(&exc
)) {
196 /* exp(finite) underflow */
197 exc
.type
= UNDERFLOW
;
198 exc
.name
= type
< 100 ? "exp" : "expf";
200 if (_LIB_VERSION
== _POSIX_
)
202 else if (!matherr(&exc
)) {
209 exc
.type
= DOMAIN
; /* should be SING for IEEE */
210 exc
.name
= type
< 100 ? "y0" : "y0f";
211 if (_LIB_VERSION
== _SVID_
)
214 exc
.retval
= -HUGE_VAL
;
215 if (_LIB_VERSION
== _POSIX_
)
217 else if (!matherr(&exc
)) {
218 if (_LIB_VERSION
== _SVID_
) {
219 (void) WRITE2("y0: DOMAIN error\n", 17);
228 exc
.name
= type
< 100 ? "y0" : "y0f";
229 if (_LIB_VERSION
== _SVID_
)
232 exc
.retval
= -HUGE_VAL
;
233 if (_LIB_VERSION
== _POSIX_
)
235 else if (!matherr(&exc
)) {
236 if (_LIB_VERSION
== _SVID_
) {
237 (void) WRITE2("y0: DOMAIN error\n", 17);
245 exc
.type
= DOMAIN
; /* should be SING for IEEE */
246 exc
.name
= type
< 100 ? "y1" : "y1f";
247 if (_LIB_VERSION
== _SVID_
)
250 exc
.retval
= -HUGE_VAL
;
251 if (_LIB_VERSION
== _POSIX_
)
253 else if (!matherr(&exc
)) {
254 if (_LIB_VERSION
== _SVID_
) {
255 (void) WRITE2("y1: DOMAIN error\n", 17);
264 exc
.name
= type
< 100 ? "y1" : "y1f";
265 if (_LIB_VERSION
== _SVID_
)
268 exc
.retval
= -HUGE_VAL
;
269 if (_LIB_VERSION
== _POSIX_
)
271 else if (!matherr(&exc
)) {
272 if (_LIB_VERSION
== _SVID_
) {
273 (void) WRITE2("y1: DOMAIN error\n", 17);
281 exc
.type
= DOMAIN
; /* should be SING for IEEE */
282 exc
.name
= type
< 100 ? "yn" : "ynf";
283 if (_LIB_VERSION
== _SVID_
)
286 exc
.retval
= -HUGE_VAL
;
287 if (_LIB_VERSION
== _POSIX_
)
289 else if (!matherr(&exc
)) {
290 if (_LIB_VERSION
== _SVID_
) {
291 (void) WRITE2("yn: DOMAIN error\n", 17);
300 exc
.name
= type
< 100 ? "yn" : "ynf";
301 if (_LIB_VERSION
== _SVID_
)
304 exc
.retval
= -HUGE_VAL
;
305 if (_LIB_VERSION
== _POSIX_
)
307 else if (!matherr(&exc
)) {
308 if (_LIB_VERSION
== _SVID_
) {
309 (void) WRITE2("yn: DOMAIN error\n", 17);
316 /* lgamma(finite) overflow */
318 exc
.name
= type
< 100 ? "lgamma" : "lgammaf";
319 if (_LIB_VERSION
== _SVID_
)
322 exc
.retval
= HUGE_VAL
;
323 if (_LIB_VERSION
== _POSIX_
)
325 else if (!matherr(&exc
)) {
331 /* lgamma(-integer) or lgamma(0) */
333 exc
.name
= type
< 100 ? "lgamma" : "lgammaf";
334 if (_LIB_VERSION
== _SVID_
)
337 exc
.retval
= HUGE_VAL
;
338 if (_LIB_VERSION
== _POSIX_
)
340 else if (!matherr(&exc
)) {
341 if (_LIB_VERSION
== _SVID_
) {
342 (void) WRITE2("lgamma: SING error\n", 19);
351 exc
.name
= type
< 100 ? "log" : "logf";
352 if (_LIB_VERSION
== _SVID_
)
355 exc
.retval
= -HUGE_VAL
;
356 if (_LIB_VERSION
== _POSIX_
)
358 else if (!matherr(&exc
)) {
359 if (_LIB_VERSION
== _SVID_
) {
360 (void) WRITE2("log: SING error\n", 16);
369 exc
.name
= type
< 100 ? "log" : "logf";
370 if (_LIB_VERSION
== _SVID_
)
373 exc
.retval
= zero
/zero
;
374 if (_LIB_VERSION
== _POSIX_
)
376 else if (!matherr(&exc
)) {
377 if (_LIB_VERSION
== _SVID_
) {
378 (void) WRITE2("log: DOMAIN error\n", 18);
387 exc
.name
= type
< 100 ? "log10" : "log10f";
388 if (_LIB_VERSION
== _SVID_
)
391 exc
.retval
= -HUGE_VAL
;
392 if (_LIB_VERSION
== _POSIX_
)
394 else if (!matherr(&exc
)) {
395 if (_LIB_VERSION
== _SVID_
) {
396 (void) WRITE2("log10: SING error\n", 18);
405 exc
.name
= type
< 100 ? "log10" : "log10f";
406 if (_LIB_VERSION
== _SVID_
)
409 exc
.retval
= zero
/zero
;
410 if (_LIB_VERSION
== _POSIX_
)
412 else if (!matherr(&exc
)) {
413 if (_LIB_VERSION
== _SVID_
) {
414 (void) WRITE2("log10: DOMAIN error\n", 20);
422 /* error only if _LIB_VERSION == _SVID_ */
424 exc
.name
= type
< 100 ? "pow" : "powf";
426 if (_LIB_VERSION
!= _SVID_
) exc
.retval
= 1.0;
427 else if (!matherr(&exc
)) {
428 (void) WRITE2("pow(0,0): DOMAIN error\n", 23);
434 /* pow(x,y) overflow */
436 exc
.name
= type
< 100 ? "pow" : "powf";
437 if (_LIB_VERSION
== _SVID_
) {
440 if(x
<zero
&&rint(y
)!=y
) exc
.retval
= -HUGE
;
442 exc
.retval
= HUGE_VAL
;
444 if(x
<zero
&&rint(y
)!=y
) exc
.retval
= -HUGE_VAL
;
446 if (_LIB_VERSION
== _POSIX_
)
448 else if (!matherr(&exc
)) {
454 /* pow(x,y) underflow */
455 exc
.type
= UNDERFLOW
;
456 exc
.name
= type
< 100 ? "pow" : "powf";
458 if (_LIB_VERSION
== _POSIX_
)
460 else if (!matherr(&exc
)) {
468 exc
.name
= type
< 100 ? "pow" : "powf";
469 if (_LIB_VERSION
== _SVID_
)
472 exc
.retval
= HUGE_VAL
;
473 if (_LIB_VERSION
== _POSIX_
)
475 else if (!matherr(&exc
)) {
476 if (_LIB_VERSION
== _SVID_
) {
477 (void) WRITE2("pow(0,neg): DOMAIN error\n", 25);
484 /* neg**non-integral */
486 exc
.name
= type
< 100 ? "pow" : "powf";
487 if (_LIB_VERSION
== _SVID_
)
490 exc
.retval
= zero
/zero
; /* X/Open allow NaN */
491 if (_LIB_VERSION
== _POSIX_
)
493 else if (!matherr(&exc
)) {
494 if (_LIB_VERSION
== _SVID_
) {
495 (void) WRITE2("neg**non-integral: DOMAIN error\n", 32);
502 /* sinh(finite) overflow */
504 exc
.name
= type
< 100 ? "sinh" : "sinhf";
505 if (_LIB_VERSION
== _SVID_
)
506 exc
.retval
= ( (x
>zero
) ? HUGE
: -HUGE
);
508 exc
.retval
= ( (x
>zero
) ? HUGE_VAL
: -HUGE_VAL
);
509 if (_LIB_VERSION
== _POSIX_
)
511 else if (!matherr(&exc
)) {
522 else if (type
== 126)
526 if (_LIB_VERSION
== _SVID_
)
529 exc
.retval
= zero
/zero
;
530 if (_LIB_VERSION
== _POSIX_
)
532 else if (!matherr(&exc
)) {
533 if (_LIB_VERSION
== _SVID_
) {
534 (void) WRITE2("sqrt: DOMAIN error\n", 19);
546 else if (type
== 127)
550 if (_LIB_VERSION
== _SVID_
)
553 exc
.retval
= zero
/zero
;
554 if (_LIB_VERSION
== _POSIX_
)
556 else if (!matherr(&exc
)) {
557 if (_LIB_VERSION
== _SVID_
) {
558 (void) WRITE2("fmod: DOMAIN error\n", 20);
567 exc
.name
= type
< 100 ? "remainder" : "remainderf";
568 exc
.retval
= zero
/zero
;
569 if (_LIB_VERSION
== _POSIX_
)
571 else if (!matherr(&exc
)) {
572 if (_LIB_VERSION
== _SVID_
) {
573 (void) WRITE2("remainder: DOMAIN error\n", 24);
582 exc
.name
= type
< 100 ? "acosh" : "acoshf";
583 exc
.retval
= zero
/zero
;
584 if (_LIB_VERSION
== _POSIX_
)
586 else if (!matherr(&exc
)) {
587 if (_LIB_VERSION
== _SVID_
) {
588 (void) WRITE2("acosh: DOMAIN error\n", 20);
597 exc
.name
= type
< 100 ? "atanh" : "atanhf";
598 exc
.retval
= zero
/zero
;
599 if (_LIB_VERSION
== _POSIX_
)
601 else if (!matherr(&exc
)) {
602 if (_LIB_VERSION
== _SVID_
) {
603 (void) WRITE2("atanh: DOMAIN error\n", 20);
612 exc
.name
= type
< 100 ? "atanh" : "atanhf";
613 exc
.retval
= x
/zero
; /* sign(x)*inf */
614 if (_LIB_VERSION
== _POSIX_
)
616 else if (!matherr(&exc
)) {
617 if (_LIB_VERSION
== _SVID_
) {
618 (void) WRITE2("atanh: SING error\n", 18);
625 /* scalb overflow; SVID also returns +-HUGE_VAL */
627 exc
.name
= type
< 100 ? "scalb" : "scalbf";
628 exc
.retval
= x
> zero
? HUGE_VAL
: -HUGE_VAL
;
629 if (_LIB_VERSION
== _POSIX_
)
631 else if (!matherr(&exc
)) {
637 /* scalb underflow */
638 exc
.type
= UNDERFLOW
;
639 exc
.name
= type
< 100 ? "scalb" : "scalbf";
640 exc
.retval
= copysign(zero
,x
);
641 if (_LIB_VERSION
== _POSIX_
)
643 else if (!matherr(&exc
)) {
649 /* j0(|x|>X_TLOSS) */
651 exc
.name
= type
< 100 ? "j0" : "j0f";
653 if (_LIB_VERSION
== _POSIX_
)
655 else if (!matherr(&exc
)) {
656 if (_LIB_VERSION
== _SVID_
) {
657 (void) WRITE2(exc
.name
, 2);
658 (void) WRITE2(": TLOSS error\n", 14);
667 exc
.name
= type
< 100 ? "y0" : "y0f";
669 if (_LIB_VERSION
== _POSIX_
)
671 else if (!matherr(&exc
)) {
672 if (_LIB_VERSION
== _SVID_
) {
673 (void) WRITE2(exc
.name
, 2);
674 (void) WRITE2(": TLOSS error\n", 14);
681 /* j1(|x|>X_TLOSS) */
683 exc
.name
= type
< 100 ? "j1" : "j1f";
685 if (_LIB_VERSION
== _POSIX_
)
687 else if (!matherr(&exc
)) {
688 if (_LIB_VERSION
== _SVID_
) {
689 (void) WRITE2(exc
.name
, 2);
690 (void) WRITE2(": TLOSS error\n", 14);
699 exc
.name
= type
< 100 ? "y1" : "y1f";
701 if (_LIB_VERSION
== _POSIX_
)
703 else if (!matherr(&exc
)) {
704 if (_LIB_VERSION
== _SVID_
) {
705 (void) WRITE2(exc
.name
, 2);
706 (void) WRITE2(": TLOSS error\n", 14);
713 /* jn(|x|>X_TLOSS) */
715 exc
.name
= type
< 100 ? "jn" : "jnf";
717 if (_LIB_VERSION
== _POSIX_
)
719 else if (!matherr(&exc
)) {
720 if (_LIB_VERSION
== _SVID_
) {
721 (void) WRITE2(exc
.name
, 2);
722 (void) WRITE2(": TLOSS error\n", 14);
731 exc
.name
= type
< 100 ? "yn" : "ynf";
733 if (_LIB_VERSION
== _POSIX_
)
735 else if (!matherr(&exc
)) {
736 if (_LIB_VERSION
== _SVID_
) {
737 (void) WRITE2(exc
.name
, 2);
738 (void) WRITE2(": TLOSS error\n", 14);
745 /* gamma(finite) overflow */
747 exc
.name
= type
< 100 ? "gamma" : "gammaf";
748 if (_LIB_VERSION
== _SVID_
)
751 exc
.retval
= HUGE_VAL
;
752 if (_LIB_VERSION
== _POSIX_
)
754 else if (!matherr(&exc
)) {
760 /* gamma(-integer) or gamma(0) */
762 exc
.name
= type
< 100 ? "gamma" : "gammaf";
763 if (_LIB_VERSION
== _SVID_
)
766 exc
.retval
= HUGE_VAL
;
767 if (_LIB_VERSION
== _POSIX_
)
769 else if (!matherr(&exc
)) {
770 if (_LIB_VERSION
== _SVID_
) {
771 (void) WRITE2("gamma: SING error\n", 18);
779 /* error only if _LIB_VERSION == _SVID_ & _XOPEN_ */
781 exc
.name
= type
< 100 ? "pow" : "powf";
783 if (_LIB_VERSION
== _IEEE_
||
784 _LIB_VERSION
== _POSIX_
) exc
.retval
= 1.0;
785 else if (!matherr(&exc
)) {
793 exc
.name
= type
< 100 ? "log2" : "log2f";
794 if (_LIB_VERSION
== _SVID_
)
797 exc
.retval
= -HUGE_VAL
;
798 if (_LIB_VERSION
== _POSIX_
)
800 else if (!matherr(&exc
)) {
801 if (_LIB_VERSION
== _SVID_
) {
802 (void) WRITE2("log2: SING error\n", 18);
811 exc
.name
= type
< 100 ? "log2" : "log2f";
812 if (_LIB_VERSION
== _SVID_
)
815 exc
.retval
= zero
/zero
;
816 if (_LIB_VERSION
== _POSIX_
)
818 else if (!matherr(&exc
)) {
819 if (_LIB_VERSION
== _SVID_
) {
820 (void) WRITE2("log2: DOMAIN error\n", 20);