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 #if defined(LIBM_SCCS) && !defined(lint)
14 static char rcsid
[] = "$NetBSD: k_standard.c,v 1.6 1995/05/10 20:46:35 jtc Exp $";
18 #include <math_private.h>
24 #include <stdio.h> /* fputs(), stderr */
25 #define WRITE2(u,v) fputs(u, stderr)
26 #else /* !defined(_USE_WRITE) */
27 #include <unistd.h> /* write */
28 #define WRITE2(u,v) write(2, u, v)
30 #endif /* !defined(_USE_WRITE) */
32 /* XXX gcc versions until now don't delay the 0.0/0.0 division until
33 runtime but produce NaN at compile time. This is wrong since the
34 exceptions are not set correctly. */
36 static const double zero
= 0.0; /* used as const */
38 static double zero
= 0.0; /* used as const */
42 * Standard conformance (non-IEEE) on exception cases.
57 * 14-- lgamma(finite) overflow
58 * 15-- lgamma(-integer)
64 * 21-- pow(x,y) overflow
65 * 22-- pow(x,y) underflow
66 * 23-- pow(0,negative)
67 * 24-- pow(neg,non-integral)
68 * 25-- sinh(finite) overflow
76 * 33-- scalb underflow
77 * 34-- j0(|x|>X_TLOSS)
79 * 36-- j1(|x|>X_TLOSS)
81 * 38-- jn(|x|>X_TLOSS, n)
82 * 39-- yn(x>X_TLOSS, n)
83 * 40-- tgamma(finite) overflow
84 * 41-- tgamma(-integer)
90 * 47-- exp10 underflow
98 __kernel_standard(double x
, double y
, int type
)
100 struct exception exc
;
101 #ifndef HUGE_VAL /* this is the only routine that uses HUGE_VAL */
105 SET_HIGH_WORD(inf
,0x7ff00000); /* set inf to infinite */
109 (void) fflush(stdout
);
119 exc
.name
= type
< 100 ? "acos" : (type
< 200
120 ? "acosf" : "acosl");;
121 if (_LIB_VERSION
== _SVID_
)
125 if (_LIB_VERSION
== _POSIX_
)
127 else if (!matherr(&exc
)) {
128 if(_LIB_VERSION
== _SVID_
) {
129 (void) WRITE2("acos: DOMAIN error\n", 19);
139 exc
.name
= type
< 100 ? "asin" : (type
< 200
140 ? "asinf" : "asinl");
141 if (_LIB_VERSION
== _SVID_
)
145 if(_LIB_VERSION
== _POSIX_
)
147 else if (!matherr(&exc
)) {
148 if(_LIB_VERSION
== _SVID_
) {
149 (void) WRITE2("asin: DOMAIN error\n", 19);
161 exc
.name
= type
< 100 ? "atan2" : (type
< 200
162 ? "atan2f" : "atan2l");
163 assert (_LIB_VERSION
== _SVID_
);
165 if(_LIB_VERSION
== _POSIX_
)
167 else if (!matherr(&exc
)) {
168 if(_LIB_VERSION
== _SVID_
) {
169 (void) WRITE2("atan2: DOMAIN error\n", 20);
177 /* hypot(finite,finite) overflow */
179 exc
.name
= type
< 100 ? "hypot" : (type
< 200
180 ? "hypotf" : "hypotl");
181 if (_LIB_VERSION
== _SVID_
)
184 exc
.retval
= HUGE_VAL
;
185 if (_LIB_VERSION
== _POSIX_
)
186 __set_errno (ERANGE
);
187 else if (!matherr(&exc
)) {
188 __set_errno (ERANGE
);
194 /* cosh(finite) overflow */
196 exc
.name
= type
< 100 ? "cosh" : (type
< 200
197 ? "coshf" : "coshl");
198 if (_LIB_VERSION
== _SVID_
)
201 exc
.retval
= HUGE_VAL
;
202 if (_LIB_VERSION
== _POSIX_
)
203 __set_errno (ERANGE
);
204 else if (!matherr(&exc
)) {
205 __set_errno (ERANGE
);
211 /* exp(finite) overflow */
213 exc
.name
= type
< 100 ? "exp" : (type
< 200
215 if (_LIB_VERSION
== _SVID_
)
218 exc
.retval
= HUGE_VAL
;
219 if (_LIB_VERSION
== _POSIX_
)
220 __set_errno (ERANGE
);
221 else if (!matherr(&exc
)) {
222 __set_errno (ERANGE
);
228 /* exp(finite) underflow */
229 exc
.type
= UNDERFLOW
;
230 exc
.name
= type
< 100 ? "exp" : (type
< 200
233 if (_LIB_VERSION
== _POSIX_
)
234 __set_errno (ERANGE
);
235 else if (!matherr(&exc
)) {
236 __set_errno (ERANGE
);
243 exc
.type
= DOMAIN
; /* should be SING for IEEE */
244 exc
.name
= type
< 100 ? "y0" : (type
< 200 ? "y0f" : "y0l");
245 if (_LIB_VERSION
== _SVID_
)
248 exc
.retval
= -HUGE_VAL
;
249 if (_LIB_VERSION
== _POSIX_
)
250 __set_errno (ERANGE
);
251 else if (!matherr(&exc
)) {
252 if (_LIB_VERSION
== _SVID_
) {
253 (void) WRITE2("y0: DOMAIN error\n", 17);
263 exc
.name
= type
< 100 ? "y0" : (type
< 200 ? "y0f" : "y0l");
264 if (_LIB_VERSION
== _SVID_
)
268 if (_LIB_VERSION
== _POSIX_
)
270 else if (!matherr(&exc
)) {
271 if (_LIB_VERSION
== _SVID_
) {
272 (void) WRITE2("y0: DOMAIN error\n", 17);
281 exc
.type
= DOMAIN
; /* should be SING for IEEE */
282 exc
.name
= type
< 100 ? "y1" : (type
< 200 ? "y1f" : "y1l");
283 if (_LIB_VERSION
== _SVID_
)
286 exc
.retval
= -HUGE_VAL
;
287 if (_LIB_VERSION
== _POSIX_
)
288 __set_errno (ERANGE
);
289 else if (!matherr(&exc
)) {
290 if (_LIB_VERSION
== _SVID_
) {
291 (void) WRITE2("y1: DOMAIN error\n", 17);
301 exc
.name
= type
< 100 ? "y1" : (type
< 200 ? "y1f" : "y1l");
302 if (_LIB_VERSION
== _SVID_
)
306 if (_LIB_VERSION
== _POSIX_
)
308 else if (!matherr(&exc
)) {
309 if (_LIB_VERSION
== _SVID_
) {
310 (void) WRITE2("y1: DOMAIN error\n", 17);
319 exc
.type
= DOMAIN
; /* should be SING for IEEE */
320 exc
.name
= type
< 100 ? "yn" : (type
< 200 ? "ynf" : "ynl");
321 if (_LIB_VERSION
== _SVID_
)
324 exc
.retval
= ((x
< 0 && ((int) x
& 1) != 0)
327 if (_LIB_VERSION
== _POSIX_
)
328 __set_errno (ERANGE
);
329 else if (!matherr(&exc
)) {
330 if (_LIB_VERSION
== _SVID_
) {
331 (void) WRITE2("yn: DOMAIN error\n", 17);
341 exc
.name
= type
< 100 ? "yn" : (type
< 200 ? "ynf" : "ynl");
342 if (_LIB_VERSION
== _SVID_
)
346 if (_LIB_VERSION
== _POSIX_
)
348 else if (!matherr(&exc
)) {
349 if (_LIB_VERSION
== _SVID_
) {
350 (void) WRITE2("yn: DOMAIN error\n", 17);
358 /* lgamma(finite) overflow */
360 exc
.name
= type
< 100 ? "lgamma" : (type
< 200
361 ? "lgammaf" : "lgammal");
362 if (_LIB_VERSION
== _SVID_
)
365 exc
.retval
= HUGE_VAL
;
366 if (_LIB_VERSION
== _POSIX_
)
367 __set_errno (ERANGE
);
368 else if (!matherr(&exc
)) {
369 __set_errno (ERANGE
);
375 /* lgamma(-integer) or lgamma(0) */
377 exc
.name
= type
< 100 ? "lgamma" : (type
< 200
378 ? "lgammaf" : "lgammal");
379 if (_LIB_VERSION
== _SVID_
)
382 exc
.retval
= HUGE_VAL
;
383 if (_LIB_VERSION
== _POSIX_
)
384 __set_errno (ERANGE
);
385 else if (!matherr(&exc
)) {
386 if (_LIB_VERSION
== _SVID_
) {
387 (void) WRITE2("lgamma: SING error\n", 19);
397 exc
.name
= type
< 100 ? "log" : (type
< 200 ? "logf" : "logl");
398 if (_LIB_VERSION
== _SVID_
)
401 exc
.retval
= -HUGE_VAL
;
402 if (_LIB_VERSION
== _POSIX_
)
403 __set_errno (ERANGE
);
404 else if (!matherr(&exc
)) {
405 if (_LIB_VERSION
== _SVID_
) {
406 (void) WRITE2("log: SING error\n", 16);
416 exc
.name
= type
< 100 ? "log" : (type
< 200 ? "logf" : "logl");
417 if (_LIB_VERSION
== _SVID_
)
421 if (_LIB_VERSION
== _POSIX_
)
423 else if (!matherr(&exc
)) {
424 if (_LIB_VERSION
== _SVID_
) {
425 (void) WRITE2("log: DOMAIN error\n", 18);
435 exc
.name
= type
< 100 ? "log10" : (type
< 200
436 ? "log10f" : "log10l");
437 if (_LIB_VERSION
== _SVID_
)
440 exc
.retval
= -HUGE_VAL
;
441 if (_LIB_VERSION
== _POSIX_
)
442 __set_errno (ERANGE
);
443 else if (!matherr(&exc
)) {
444 if (_LIB_VERSION
== _SVID_
) {
445 (void) WRITE2("log10: SING error\n", 18);
455 exc
.name
= type
< 100 ? "log10" : (type
< 200
456 ? "log10f" : "log10l");
457 if (_LIB_VERSION
== _SVID_
)
461 if (_LIB_VERSION
== _POSIX_
)
463 else if (!matherr(&exc
)) {
464 if (_LIB_VERSION
== _SVID_
) {
465 (void) WRITE2("log10: DOMAIN error\n", 20);
474 /* error only if _LIB_VERSION == _SVID_ */
476 exc
.name
= type
< 100 ? "pow" : (type
< 200 ? "powf" : "powl");
478 if (_LIB_VERSION
!= _SVID_
) exc
.retval
= 1.0;
479 else if (!matherr(&exc
)) {
480 (void) WRITE2("pow(0,0): DOMAIN error\n", 23);
487 /* pow(x,y) overflow */
489 exc
.name
= type
< 100 ? "pow" : (type
< 200 ? "powf" : "powl");
490 if (_LIB_VERSION
== _SVID_
) {
493 if(x
<zero
&&__rint(y
)!=y
) exc
.retval
= -HUGE
;
495 exc
.retval
= HUGE_VAL
;
497 if(x
<zero
&&__rint(y
)!=y
) exc
.retval
= -HUGE_VAL
;
499 if (_LIB_VERSION
== _POSIX_
)
500 __set_errno (ERANGE
);
501 else if (!matherr(&exc
)) {
502 __set_errno (ERANGE
);
508 /* pow(x,y) underflow */
509 exc
.type
= UNDERFLOW
;
510 exc
.name
= type
< 100 ? "pow" : (type
< 200 ? "powf" : "powl");
513 if (x
< zero
&& __rint (y
) != y
)
515 if (_LIB_VERSION
== _POSIX_
)
516 __set_errno (ERANGE
);
517 else if (!matherr(&exc
)) {
518 __set_errno (ERANGE
);
526 exc
.name
= type
< 100 ? "pow" : (type
< 200 ? "powf" : "powl");
527 if (_LIB_VERSION
== _SVID_
)
530 exc
.retval
= -HUGE_VAL
;
531 if (_LIB_VERSION
== _POSIX_
)
532 __set_errno (ERANGE
);
533 else if (!matherr(&exc
)) {
534 if (_LIB_VERSION
== _SVID_
) {
535 (void) WRITE2("pow(0,neg): DOMAIN error\n", 25);
545 exc
.name
= type
< 100 ? "pow" : (type
< 200 ? "powf" : "powl");
546 if (_LIB_VERSION
== _SVID_
)
549 exc
.retval
= HUGE_VAL
;
550 if (_LIB_VERSION
== _POSIX_
)
551 __set_errno (ERANGE
);
552 else if (!matherr(&exc
)) {
553 if (_LIB_VERSION
== _SVID_
) {
554 (void) WRITE2("pow(0,neg): DOMAIN error\n", 25);
562 /* neg**non-integral */
564 exc
.name
= type
< 100 ? "pow" : (type
< 200 ? "powf" : "powl");
565 if (_LIB_VERSION
== _SVID_
)
568 exc
.retval
= zero
/zero
; /* X/Open allow NaN */
569 if (_LIB_VERSION
== _POSIX_
)
571 else if (!matherr(&exc
)) {
572 if (_LIB_VERSION
== _SVID_
) {
573 (void) WRITE2("neg**non-integral: DOMAIN error\n", 32);
581 /* sinh(finite) overflow */
583 exc
.name
= type
< 100 ? "sinh" : (type
< 200
584 ? "sinhf" : "sinhl");
585 if (_LIB_VERSION
== _SVID_
)
586 exc
.retval
= ( (x
>zero
) ? HUGE
: -HUGE
);
588 exc
.retval
= ( (x
>zero
) ? HUGE_VAL
: -HUGE_VAL
);
589 if (_LIB_VERSION
== _POSIX_
)
590 __set_errno (ERANGE
);
591 else if (!matherr(&exc
)) {
592 __set_errno (ERANGE
);
600 exc
.name
= type
< 100 ? "sqrt" : (type
< 200
601 ? "sqrtf" : "sqrtl");
602 if (_LIB_VERSION
== _SVID_
)
605 exc
.retval
= zero
/zero
;
606 if (_LIB_VERSION
== _POSIX_
)
608 else if (!matherr(&exc
)) {
609 if (_LIB_VERSION
== _SVID_
) {
610 (void) WRITE2("sqrt: DOMAIN error\n", 19);
620 exc
.name
= type
< 100 ? "fmod" : (type
< 200
621 ? "fmodf" : "fmodl");
622 if (_LIB_VERSION
== _SVID_
)
625 exc
.retval
= zero
/zero
;
626 if (_LIB_VERSION
== _POSIX_
)
628 else if (!matherr(&exc
)) {
629 if (_LIB_VERSION
== _SVID_
) {
630 (void) WRITE2("fmod: DOMAIN error\n", 20);
640 exc
.name
= type
< 100 ? "remainder" : (type
< 200
643 exc
.retval
= zero
/zero
;
644 if (_LIB_VERSION
== _POSIX_
)
646 else if (!matherr(&exc
)) {
647 if (_LIB_VERSION
== _SVID_
) {
648 (void) WRITE2("remainder: DOMAIN error\n", 24);
658 exc
.name
= type
< 100 ? "acosh" : (type
< 200
659 ? "acoshf" : "acoshl");
660 exc
.retval
= zero
/zero
;
661 if (_LIB_VERSION
== _POSIX_
)
663 else if (!matherr(&exc
)) {
664 if (_LIB_VERSION
== _SVID_
) {
665 (void) WRITE2("acosh: DOMAIN error\n", 20);
675 exc
.name
= type
< 100 ? "atanh" : (type
< 200
676 ? "atanhf" : "atanhl");
677 exc
.retval
= zero
/zero
;
678 if (_LIB_VERSION
== _POSIX_
)
680 else if (!matherr(&exc
)) {
681 if (_LIB_VERSION
== _SVID_
) {
682 (void) WRITE2("atanh: DOMAIN error\n", 20);
692 exc
.name
= type
< 100 ? "atanh" : (type
< 200
693 ? "atanhf" : "atanhl");
694 exc
.retval
= x
/zero
; /* sign(x)*inf */
695 if (_LIB_VERSION
== _POSIX_
)
696 __set_errno (ERANGE
);
697 else if (!matherr(&exc
)) {
698 if (_LIB_VERSION
== _SVID_
) {
699 (void) WRITE2("atanh: SING error\n", 18);
707 /* scalb overflow; SVID also returns +-HUGE_VAL */
709 exc
.name
= type
< 100 ? "scalb" : (type
< 200
710 ? "scalbf" : "scalbl");
711 exc
.retval
= x
> zero
? HUGE_VAL
: -HUGE_VAL
;
712 if (_LIB_VERSION
== _POSIX_
)
713 __set_errno (ERANGE
);
714 else if (!matherr(&exc
)) {
715 __set_errno (ERANGE
);
721 /* scalb underflow */
722 exc
.type
= UNDERFLOW
;
723 exc
.name
= type
< 100 ? "scalb" : (type
< 200
724 ? "scalbf" : "scalbl");
725 exc
.retval
= __copysign(zero
,x
);
726 if (_LIB_VERSION
== _POSIX_
)
727 __set_errno (ERANGE
);
728 else if (!matherr(&exc
)) {
729 __set_errno (ERANGE
);
735 /* j0(|x|>X_TLOSS) */
737 exc
.name
= type
< 100 ? "j0" : (type
< 200 ? "j0f" : "j0l");
739 if (_LIB_VERSION
== _POSIX_
)
740 __set_errno (ERANGE
);
741 else if (!matherr(&exc
)) {
742 if (_LIB_VERSION
== _SVID_
) {
743 (void) WRITE2(exc
.name
, 2);
744 (void) WRITE2(": TLOSS error\n", 14);
746 __set_errno (ERANGE
);
754 exc
.name
= type
< 100 ? "y0" : (type
< 200 ? "y0f" : "y0l");
756 if (_LIB_VERSION
== _POSIX_
)
757 __set_errno (ERANGE
);
758 else if (!matherr(&exc
)) {
759 if (_LIB_VERSION
== _SVID_
) {
760 (void) WRITE2(exc
.name
, 2);
761 (void) WRITE2(": TLOSS error\n", 14);
763 __set_errno (ERANGE
);
769 /* j1(|x|>X_TLOSS) */
771 exc
.name
= type
< 100 ? "j1" : (type
< 200 ? "j1f" : "j1l");
773 if (_LIB_VERSION
== _POSIX_
)
774 __set_errno (ERANGE
);
775 else if (!matherr(&exc
)) {
776 if (_LIB_VERSION
== _SVID_
) {
777 (void) WRITE2(exc
.name
, 2);
778 (void) WRITE2(": TLOSS error\n", 14);
780 __set_errno (ERANGE
);
788 exc
.name
= type
< 100 ? "y1" : (type
< 200 ? "y1f" : "y1l");
790 if (_LIB_VERSION
== _POSIX_
)
791 __set_errno (ERANGE
);
792 else if (!matherr(&exc
)) {
793 if (_LIB_VERSION
== _SVID_
) {
794 (void) WRITE2(exc
.name
, 2);
795 (void) WRITE2(": TLOSS error\n", 14);
797 __set_errno (ERANGE
);
803 /* jn(|x|>X_TLOSS) */
805 exc
.name
= type
< 100 ? "jn" : (type
< 200 ? "jnf" : "jnl");
807 if (_LIB_VERSION
== _POSIX_
)
808 __set_errno (ERANGE
);
809 else if (!matherr(&exc
)) {
810 if (_LIB_VERSION
== _SVID_
) {
811 (void) WRITE2(exc
.name
, 2);
812 (void) WRITE2(": TLOSS error\n", 14);
814 __set_errno (ERANGE
);
822 exc
.name
= type
< 100 ? "yn" : (type
< 200 ? "ynf" : "ynl");
824 if (_LIB_VERSION
== _POSIX_
)
825 __set_errno (ERANGE
);
826 else if (!matherr(&exc
)) {
827 if (_LIB_VERSION
== _SVID_
) {
828 (void) WRITE2(exc
.name
, 2);
829 (void) WRITE2(": TLOSS error\n", 14);
831 __set_errno (ERANGE
);
837 /* tgamma(finite) overflow */
839 exc
.name
= type
< 100 ? "tgamma" : (type
< 200
840 ? "tgammaf" : "tgammal");
841 exc
.retval
= __copysign (HUGE_VAL
, x
);
842 if (_LIB_VERSION
== _POSIX_
)
843 __set_errno (ERANGE
);
844 else if (!matherr(&exc
)) {
845 __set_errno (ERANGE
);
851 /* tgamma(-integer) */
853 exc
.name
= type
< 100 ? "tgamma" : (type
< 200
854 ? "tgammaf" : "tgammal");
856 if (_LIB_VERSION
== _POSIX_
)
858 else if (!matherr(&exc
)) {
859 if (_LIB_VERSION
== _SVID_
) {
860 (void) WRITE2("tgamma: SING error\n", 18);
861 exc
.retval
= HUGE_VAL
;
870 /* error only if _LIB_VERSION == _SVID_ & _XOPEN_ */
872 exc
.name
= type
< 100 ? "pow" : (type
< 200 ? "powf" : "powl");
874 if (_LIB_VERSION
== _IEEE_
||
875 _LIB_VERSION
== _POSIX_
) exc
.retval
= 1.0;
876 else if (!matherr(&exc
)) {
884 /* exp(finite) overflow */
886 exc
.name
= type
< 100 ? "exp2" : (type
< 200
887 ? "exp2f" : "exp2l");
888 if (_LIB_VERSION
== _SVID_
)
891 exc
.retval
= HUGE_VAL
;
892 if (_LIB_VERSION
== _POSIX_
)
893 __set_errno (ERANGE
);
894 else if (!matherr(&exc
)) {
895 __set_errno (ERANGE
);
901 /* exp(finite) underflow */
902 exc
.type
= UNDERFLOW
;
903 exc
.name
= type
< 100 ? "exp2" : (type
< 200
904 ? "exp2f" : "exp2l");
906 if (_LIB_VERSION
== _POSIX_
)
907 __set_errno (ERANGE
);
908 else if (!matherr(&exc
)) {
909 __set_errno (ERANGE
);
916 /* exp(finite) overflow */
918 exc
.name
= type
< 100 ? "exp10" : (type
< 200
919 ? "exp10f" : "exp10l");
920 if (_LIB_VERSION
== _SVID_
)
923 exc
.retval
= HUGE_VAL
;
924 if (_LIB_VERSION
== _POSIX_
)
925 __set_errno (ERANGE
);
926 else if (!matherr(&exc
)) {
927 __set_errno (ERANGE
);
933 /* exp(finite) underflow */
934 exc
.type
= UNDERFLOW
;
935 exc
.name
= type
< 100 ? "exp10" : (type
< 200
936 ? "exp10f" : "exp10l");
938 if (_LIB_VERSION
== _POSIX_
)
939 __set_errno (ERANGE
);
940 else if (!matherr(&exc
)) {
941 __set_errno (ERANGE
);
949 exc
.name
= type
< 100 ? "log2" : (type
< 200
950 ? "log2f" : "log2l");
951 if (_LIB_VERSION
== _SVID_
)
954 exc
.retval
= -HUGE_VAL
;
955 if (_LIB_VERSION
== _POSIX_
)
956 __set_errno (ERANGE
);
957 else if (!matherr(&exc
)) {
966 exc
.name
= type
< 100 ? "log2" : (type
< 200
967 ? "log2f" : "log2l");
968 if (_LIB_VERSION
== _SVID_
)
972 if (_LIB_VERSION
== _POSIX_
)
974 else if (!matherr(&exc
)) {
983 exc
.name
= type
< 100 ? "tgamma" : (type
< 200
984 ? "tgammaf" : "tgammal");
985 exc
.retval
= __copysign (HUGE_VAL
, x
);
986 if (_LIB_VERSION
== _POSIX_
)
987 __set_errno (ERANGE
);
988 else if (!matherr(&exc
)) {
989 if (_LIB_VERSION
== _SVID_
)
990 (void) WRITE2("tgamma: SING error\n", 18);
991 __set_errno (ERANGE
);
995 /* #### Last used is 50/150/250 ### */