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 copile 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_)
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_)
267 exc.retval = -HUGE_VAL;
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_)
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_)
305 exc.retval = -HUGE_VAL;
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 = -HUGE_VAL;
325 if (_LIB_VERSION == _POSIX_)
327 else if (!matherr(&exc)) {
328 if (_LIB_VERSION == _SVID_) {
329 (void) WRITE2("yn: DOMAIN error\n", 17);
339 exc.name = type < 100 ? "yn" : (type < 200 ? "ynf" : "ynl");
340 if (_LIB_VERSION == _SVID_)
343 exc.retval = -HUGE_VAL;
344 if (_LIB_VERSION == _POSIX_)
346 else if (!matherr(&exc)) {
347 if (_LIB_VERSION == _SVID_) {
348 (void) WRITE2("yn: DOMAIN error\n", 17);
356 /* lgamma(finite) overflow */
358 exc.name = type < 100 ? "lgamma" : (type < 200
359 ? "lgammaf" : "lgammal");
360 if (_LIB_VERSION == _SVID_)
363 exc.retval = HUGE_VAL;
364 if (_LIB_VERSION == _POSIX_)
365 __set_errno (ERANGE);
366 else if (!matherr(&exc)) {
367 __set_errno (ERANGE);
373 /* lgamma(-integer) or lgamma(0) */
375 exc.name = type < 100 ? "lgamma" : (type < 200
376 ? "lgammaf" : "lgammal");
377 if (_LIB_VERSION == _SVID_)
380 exc.retval = HUGE_VAL;
381 if (_LIB_VERSION == _POSIX_)
382 __set_errno (ERANGE);
383 else if (!matherr(&exc)) {
384 if (_LIB_VERSION == _SVID_) {
385 (void) WRITE2("lgamma: SING error\n", 19);
395 exc.name = type < 100 ? "log" : (type < 200 ? "logf" : "logl");
396 if (_LIB_VERSION == _SVID_)
399 exc.retval = -HUGE_VAL;
400 if (_LIB_VERSION == _POSIX_)
401 __set_errno (ERANGE);
402 else if (!matherr(&exc)) {
403 if (_LIB_VERSION == _SVID_) {
404 (void) WRITE2("log: SING error\n", 16);
414 exc.name = type < 100 ? "log" : (type < 200 ? "logf" : "logl");
415 if (_LIB_VERSION == _SVID_)
419 if (_LIB_VERSION == _POSIX_)
421 else if (!matherr(&exc)) {
422 if (_LIB_VERSION == _SVID_) {
423 (void) WRITE2("log: DOMAIN error\n", 18);
433 exc.name = type < 100 ? "log10" : (type < 200
434 ? "log10f" : "log10l");
435 if (_LIB_VERSION == _SVID_)
438 exc.retval = -HUGE_VAL;
439 if (_LIB_VERSION == _POSIX_)
440 __set_errno (ERANGE);
441 else if (!matherr(&exc)) {
442 if (_LIB_VERSION == _SVID_) {
443 (void) WRITE2("log10: SING error\n", 18);
453 exc.name = type < 100 ? "log10" : (type < 200
454 ? "log10f" : "log10l");
455 if (_LIB_VERSION == _SVID_)
459 if (_LIB_VERSION == _POSIX_)
461 else if (!matherr(&exc)) {
462 if (_LIB_VERSION == _SVID_) {
463 (void) WRITE2("log10: DOMAIN error\n", 20);
472 /* error only if _LIB_VERSION == _SVID_ */
474 exc.name = type < 100 ? "pow" : (type < 200 ? "powf" : "powl");
476 if (_LIB_VERSION != _SVID_) exc.retval = 1.0;
477 else if (!matherr(&exc)) {
478 (void) WRITE2("pow(0,0): DOMAIN error\n", 23);
485 /* pow(x,y) overflow */
487 exc.name = type < 100 ? "pow" : (type < 200 ? "powf" : "powl");
488 if (_LIB_VERSION == _SVID_) {
491 if(x<zero&&__rint(y)!=y) exc.retval = -HUGE;
493 exc.retval = HUGE_VAL;
495 if(x<zero&&__rint(y)!=y) exc.retval = -HUGE_VAL;
497 if (_LIB_VERSION == _POSIX_)
498 __set_errno (ERANGE);
499 else if (!matherr(&exc)) {
500 __set_errno (ERANGE);
506 /* pow(x,y) underflow */
507 exc.type = UNDERFLOW;
508 exc.name = type < 100 ? "pow" : (type < 200 ? "powf" : "powl");
510 if (_LIB_VERSION == _POSIX_)
511 __set_errno (ERANGE);
512 else if (!matherr(&exc)) {
513 __set_errno (ERANGE);
521 exc.name = type < 100 ? "pow" : (type < 200 ? "powf" : "powl");
522 if (_LIB_VERSION == _SVID_)
525 exc.retval = -HUGE_VAL;
526 if (_LIB_VERSION == _POSIX_)
527 __set_errno (ERANGE);
528 else if (!matherr(&exc)) {
529 if (_LIB_VERSION == _SVID_) {
530 (void) WRITE2("pow(0,neg): DOMAIN error\n", 25);
540 exc.name = type < 100 ? "pow" : (type < 200 ? "powf" : "powl");
541 if (_LIB_VERSION == _SVID_)
544 exc.retval = HUGE_VAL;
545 if (_LIB_VERSION == _POSIX_)
546 __set_errno (ERANGE);
547 else if (!matherr(&exc)) {
548 if (_LIB_VERSION == _SVID_) {
549 (void) WRITE2("pow(0,neg): DOMAIN error\n", 25);
557 /* neg**non-integral */
559 exc.name = type < 100 ? "pow" : (type < 200 ? "powf" : "powl");
560 if (_LIB_VERSION == _SVID_)
563 exc.retval = zero/zero; /* X/Open allow NaN */
564 if (_LIB_VERSION == _POSIX_)
566 else if (!matherr(&exc)) {
567 if (_LIB_VERSION == _SVID_) {
568 (void) WRITE2("neg**non-integral: DOMAIN error\n", 32);
576 /* sinh(finite) overflow */
578 exc.name = type < 100 ? "sinh" : (type < 200
579 ? "sinhf" : "sinhl");
580 if (_LIB_VERSION == _SVID_)
581 exc.retval = ( (x>zero) ? HUGE : -HUGE);
583 exc.retval = ( (x>zero) ? HUGE_VAL : -HUGE_VAL);
584 if (_LIB_VERSION == _POSIX_)
585 __set_errno (ERANGE);
586 else if (!matherr(&exc)) {
587 __set_errno (ERANGE);
595 exc.name = type < 100 ? "sqrt" : (type < 200
596 ? "sqrtf" : "sqrtl");
597 if (_LIB_VERSION == _SVID_)
600 exc.retval = zero/zero;
601 if (_LIB_VERSION == _POSIX_)
603 else if (!matherr(&exc)) {
604 if (_LIB_VERSION == _SVID_) {
605 (void) WRITE2("sqrt: DOMAIN error\n", 19);
615 exc.name = type < 100 ? "fmod" : (type < 200
616 ? "fmodf" : "fmodl");
617 if (_LIB_VERSION == _SVID_)
620 exc.retval = zero/zero;
621 if (_LIB_VERSION == _POSIX_)
623 else if (!matherr(&exc)) {
624 if (_LIB_VERSION == _SVID_) {
625 (void) WRITE2("fmod: DOMAIN error\n", 20);
635 exc.name = type < 100 ? "remainder" : (type < 200
638 exc.retval = zero/zero;
639 if (_LIB_VERSION == _POSIX_)
641 else if (!matherr(&exc)) {
642 if (_LIB_VERSION == _SVID_) {
643 (void) WRITE2("remainder: DOMAIN error\n", 24);
653 exc.name = type < 100 ? "acosh" : (type < 200
654 ? "acoshf" : "acoshl");
655 exc.retval = zero/zero;
656 if (_LIB_VERSION == _POSIX_)
658 else if (!matherr(&exc)) {
659 if (_LIB_VERSION == _SVID_) {
660 (void) WRITE2("acosh: DOMAIN error\n", 20);
670 exc.name = type < 100 ? "atanh" : (type < 200
671 ? "atanhf" : "atanhl");
672 exc.retval = zero/zero;
673 if (_LIB_VERSION == _POSIX_)
675 else if (!matherr(&exc)) {
676 if (_LIB_VERSION == _SVID_) {
677 (void) WRITE2("atanh: DOMAIN error\n", 20);
687 exc.name = type < 100 ? "atanh" : (type < 200
688 ? "atanhf" : "atanhl");
689 exc.retval = x/zero; /* sign(x)*inf */
690 if (_LIB_VERSION == _POSIX_)
691 __set_errno (ERANGE);
692 else if (!matherr(&exc)) {
693 if (_LIB_VERSION == _SVID_) {
694 (void) WRITE2("atanh: SING error\n", 18);
702 /* scalb overflow; SVID also returns +-HUGE_VAL */
704 exc.name = type < 100 ? "scalb" : (type < 200
705 ? "scalbf" : "scalbl");
706 exc.retval = x > zero ? HUGE_VAL : -HUGE_VAL;
707 if (_LIB_VERSION == _POSIX_)
708 __set_errno (ERANGE);
709 else if (!matherr(&exc)) {
710 __set_errno (ERANGE);
716 /* scalb underflow */
717 exc.type = UNDERFLOW;
718 exc.name = type < 100 ? "scalb" : (type < 200
719 ? "scalbf" : "scalbl");
720 exc.retval = __copysign(zero,x);
721 if (_LIB_VERSION == _POSIX_)
722 __set_errno (ERANGE);
723 else if (!matherr(&exc)) {
724 __set_errno (ERANGE);
730 /* j0(|x|>X_TLOSS) */
732 exc.name = type < 100 ? "j0" : (type < 200 ? "j0f" : "j0l");
734 if (_LIB_VERSION == _POSIX_)
735 __set_errno (ERANGE);
736 else if (!matherr(&exc)) {
737 if (_LIB_VERSION == _SVID_) {
738 (void) WRITE2(exc.name, 2);
739 (void) WRITE2(": TLOSS error\n", 14);
741 __set_errno (ERANGE);
749 exc.name = type < 100 ? "y0" : (type < 200 ? "y0f" : "y0l");
751 if (_LIB_VERSION == _POSIX_)
752 __set_errno (ERANGE);
753 else if (!matherr(&exc)) {
754 if (_LIB_VERSION == _SVID_) {
755 (void) WRITE2(exc.name, 2);
756 (void) WRITE2(": TLOSS error\n", 14);
758 __set_errno (ERANGE);
764 /* j1(|x|>X_TLOSS) */
766 exc.name = type < 100 ? "j1" : (type < 200 ? "j1f" : "j1l");
768 if (_LIB_VERSION == _POSIX_)
769 __set_errno (ERANGE);
770 else if (!matherr(&exc)) {
771 if (_LIB_VERSION == _SVID_) {
772 (void) WRITE2(exc.name, 2);
773 (void) WRITE2(": TLOSS error\n", 14);
775 __set_errno (ERANGE);
783 exc.name = type < 100 ? "y1" : (type < 200 ? "y1f" : "y1l");
785 if (_LIB_VERSION == _POSIX_)
786 __set_errno (ERANGE);
787 else if (!matherr(&exc)) {
788 if (_LIB_VERSION == _SVID_) {
789 (void) WRITE2(exc.name, 2);
790 (void) WRITE2(": TLOSS error\n", 14);
792 __set_errno (ERANGE);
798 /* jn(|x|>X_TLOSS) */
800 exc.name = type < 100 ? "jn" : (type < 200 ? "jnf" : "jnl");
802 if (_LIB_VERSION == _POSIX_)
803 __set_errno (ERANGE);
804 else if (!matherr(&exc)) {
805 if (_LIB_VERSION == _SVID_) {
806 (void) WRITE2(exc.name, 2);
807 (void) WRITE2(": TLOSS error\n", 14);
809 __set_errno (ERANGE);
817 exc.name = type < 100 ? "yn" : (type < 200 ? "ynf" : "ynl");
819 if (_LIB_VERSION == _POSIX_)
820 __set_errno (ERANGE);
821 else if (!matherr(&exc)) {
822 if (_LIB_VERSION == _SVID_) {
823 (void) WRITE2(exc.name, 2);
824 (void) WRITE2(": TLOSS error\n", 14);
826 __set_errno (ERANGE);
832 /* tgamma(finite) overflow */
834 exc.name = type < 100 ? "tgamma" : (type < 200
835 ? "tgammaf" : "tgammal");
836 exc.retval = HUGE_VAL;
837 if (_LIB_VERSION == _POSIX_)
838 __set_errno (ERANGE);
839 else if (!matherr(&exc)) {
840 __set_errno (ERANGE);
846 /* tgamma(-integer) */
848 exc.name = type < 100 ? "tgamma" : (type < 200
849 ? "tgammaf" : "tgammal");
851 if (_LIB_VERSION == _POSIX_)
853 else if (!matherr(&exc)) {
854 if (_LIB_VERSION == _SVID_) {
855 (void) WRITE2("tgamma: SING error\n", 18);
856 exc.retval = HUGE_VAL;
865 /* error only if _LIB_VERSION == _SVID_ & _XOPEN_ */
867 exc.name = type < 100 ? "pow" : (type < 200 ? "powf" : "powl");
869 if (_LIB_VERSION == _IEEE_ ||
870 _LIB_VERSION == _POSIX_) exc.retval = 1.0;
871 else if (!matherr(&exc)) {
879 /* exp(finite) overflow */
881 exc.name = type < 100 ? "exp2" : (type < 200
882 ? "exp2f" : "exp2l");
883 if (_LIB_VERSION == _SVID_)
886 exc.retval = HUGE_VAL;
887 if (_LIB_VERSION == _POSIX_)
888 __set_errno (ERANGE);
889 else if (!matherr(&exc)) {
890 __set_errno (ERANGE);
896 /* exp(finite) underflow */
897 exc.type = UNDERFLOW;
898 exc.name = type < 100 ? "exp2" : (type < 200
899 ? "exp2f" : "exp2l");
901 if (_LIB_VERSION == _POSIX_)
902 __set_errno (ERANGE);
903 else if (!matherr(&exc)) {
904 __set_errno (ERANGE);
911 /* exp(finite) overflow */
913 exc.name = type < 100 ? "exp10" : (type < 200
914 ? "exp10f" : "exp10l");
915 if (_LIB_VERSION == _SVID_)
918 exc.retval = HUGE_VAL;
919 if (_LIB_VERSION == _POSIX_)
920 __set_errno (ERANGE);
921 else if (!matherr(&exc)) {
922 __set_errno (ERANGE);
928 /* exp(finite) underflow */
929 exc.type = UNDERFLOW;
930 exc.name = type < 100 ? "exp10" : (type < 200
931 ? "exp10f" : "exp10l");
933 if (_LIB_VERSION == _POSIX_)
934 __set_errno (ERANGE);
935 else if (!matherr(&exc)) {
936 __set_errno (ERANGE);
944 exc.name = type < 100 ? "log2" : (type < 200
945 ? "log2f" : "log2l");
946 if (_LIB_VERSION == _SVID_)
949 exc.retval = -HUGE_VAL;
950 if (_LIB_VERSION == _POSIX_)
951 __set_errno (ERANGE);
952 else if (!matherr(&exc)) {
961 exc.name = type < 100 ? "log2" : (type < 200
962 ? "log2f" : "log2l");
963 if (_LIB_VERSION == _SVID_)
967 if (_LIB_VERSION == _POSIX_)
969 else if (!matherr(&exc)) {
978 exc.name = type < 100 ? "tgamma" : (type < 200
979 ? "tgammaf" : "tgammal");
980 exc.retval = __copysign (HUGE_VAL, x);
981 if (_LIB_VERSION == _POSIX_)
982 __set_errno (ERANGE);
983 else if (!matherr(&exc)) {
984 if (_LIB_VERSION == _SVID_)
985 (void) WRITE2("tgamma: SING error\n", 18);
986 __set_errno (ERANGE);
990 /* #### Last used is 50/150/250 ### */
997 __kernel_standard_f(float x, float y, int type)
999 return __kernel_standard(x, y, type);