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>
19 #include <math-svid-compat.h>
27 # include <stdio.h> /* fputs(), stderr */
28 # define WRITE2(u,v) fputs(u, stderr)
29 # else /* !defined(_USE_WRITE) */
30 # include <unistd.h> /* write */
31 # define WRITE2(u,v) write(2, u, v)
33 # endif /* !defined(_USE_WRITE) */
35 /* XXX gcc versions until now don't delay the 0.0/0.0 division until
36 runtime but produce NaN at compile time. This is wrong since the
37 exceptions are not set correctly. */
39 static const double zero = 0.0; /* used as const */
41 static double zero = 0.0; /* used as const */
45 * Standard conformance (non-IEEE) on exception cases.
60 * 14-- lgamma(finite) overflow
61 * 15-- lgamma(-integer)
66 * 21-- pow(x,y) overflow
67 * 22-- pow(x,y) underflow
68 * 23-- pow(0,negative)
69 * 24-- pow(neg,non-integral)
70 * 25-- sinh(finite) overflow
78 * 33-- scalb underflow
79 * 34-- j0(|x|>X_TLOSS)
81 * 36-- j1(|x|>X_TLOSS)
83 * 38-- jn(|x|>X_TLOSS, n)
84 * 39-- yn(x>X_TLOSS, n)
85 * 40-- tgamma(finite) overflow
86 * 41-- tgamma(-integer)
91 * 47-- exp10 underflow
99 __kernel_standard(double x, double y, int type)
101 struct exception exc;
102 # ifndef HUGE_VAL /* this is the only routine that uses HUGE_VAL */
103 # define HUGE_VAL inf
106 SET_HIGH_WORD(inf,0x7ff00000); /* set inf to infinite */
109 /* The SVID struct exception uses a field "char *name;". */
110 # define CSTR(func) ((char *) (type < 100 \
112 : (type < 200 ? func "f" : func "l")))
115 (void) fflush(stdout);
125 exc.name = CSTR ("acos");
126 if (_LIB_VERSION == _SVID_)
130 if (_LIB_VERSION == _POSIX_)
132 else if (!matherr(&exc)) {
133 if(_LIB_VERSION == _SVID_) {
134 (void) WRITE2("acos: DOMAIN error\n", 19);
144 exc.name = CSTR ("asin");
145 if (_LIB_VERSION == _SVID_)
149 if(_LIB_VERSION == _POSIX_)
151 else if (!matherr(&exc)) {
152 if(_LIB_VERSION == _SVID_) {
153 (void) WRITE2("asin: DOMAIN error\n", 19);
165 exc.name = CSTR ("atan2");
166 assert (_LIB_VERSION == _SVID_);
168 if(_LIB_VERSION == _POSIX_)
170 else if (!matherr(&exc)) {
171 if(_LIB_VERSION == _SVID_) {
172 (void) WRITE2("atan2: DOMAIN error\n", 20);
180 /* hypot(finite,finite) overflow */
182 exc.name = CSTR ("hypot");
183 if (_LIB_VERSION == _SVID_)
186 exc.retval = HUGE_VAL;
187 if (_LIB_VERSION == _POSIX_)
188 __set_errno (ERANGE);
189 else if (!matherr(&exc)) {
190 __set_errno (ERANGE);
196 /* cosh(finite) overflow */
198 exc.name = CSTR ("cosh");
199 if (_LIB_VERSION == _SVID_)
202 exc.retval = HUGE_VAL;
203 if (_LIB_VERSION == _POSIX_)
204 __set_errno (ERANGE);
205 else if (!matherr(&exc)) {
206 __set_errno (ERANGE);
212 /* exp(finite) overflow */
214 exc.name = CSTR ("exp");
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 = CSTR ("exp");
232 if (_LIB_VERSION == _POSIX_)
233 __set_errno (ERANGE);
234 else if (!matherr(&exc)) {
235 __set_errno (ERANGE);
242 exc.type = DOMAIN; /* should be SING for IEEE */
243 exc.name = CSTR ("y0");
244 if (_LIB_VERSION == _SVID_)
247 exc.retval = -HUGE_VAL;
248 if (_LIB_VERSION == _POSIX_)
249 __set_errno (ERANGE);
250 else if (!matherr(&exc)) {
251 if (_LIB_VERSION == _SVID_) {
252 (void) WRITE2("y0: DOMAIN error\n", 17);
262 exc.name = CSTR ("y0");
263 if (_LIB_VERSION == _SVID_)
267 if (_LIB_VERSION == _POSIX_)
269 else if (!matherr(&exc)) {
270 if (_LIB_VERSION == _SVID_) {
271 (void) WRITE2("y0: DOMAIN error\n", 17);
280 exc.type = DOMAIN; /* should be SING for IEEE */
281 exc.name = CSTR ("y1");
282 if (_LIB_VERSION == _SVID_)
285 exc.retval = -HUGE_VAL;
286 if (_LIB_VERSION == _POSIX_)
287 __set_errno (ERANGE);
288 else if (!matherr(&exc)) {
289 if (_LIB_VERSION == _SVID_) {
290 (void) WRITE2("y1: DOMAIN error\n", 17);
300 exc.name = CSTR ("y1");
301 if (_LIB_VERSION == _SVID_)
305 if (_LIB_VERSION == _POSIX_)
307 else if (!matherr(&exc)) {
308 if (_LIB_VERSION == _SVID_) {
309 (void) WRITE2("y1: DOMAIN error\n", 17);
318 exc.type = DOMAIN; /* should be SING for IEEE */
319 exc.name = CSTR ("yn");
320 if (_LIB_VERSION == _SVID_)
323 exc.retval = ((x < 0 && ((int) x & 1) != 0)
326 if (_LIB_VERSION == _POSIX_)
327 __set_errno (ERANGE);
328 else if (!matherr(&exc)) {
329 if (_LIB_VERSION == _SVID_) {
330 (void) WRITE2("yn: DOMAIN error\n", 17);
340 exc.name = CSTR ("yn");
341 if (_LIB_VERSION == _SVID_)
345 if (_LIB_VERSION == _POSIX_)
347 else if (!matherr(&exc)) {
348 if (_LIB_VERSION == _SVID_) {
349 (void) WRITE2("yn: DOMAIN error\n", 17);
357 /* lgamma(finite) overflow */
359 exc.name = CSTR ("lgamma");
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 = CSTR ("lgamma");
376 if (_LIB_VERSION == _SVID_)
379 exc.retval = HUGE_VAL;
380 if (_LIB_VERSION == _POSIX_)
381 __set_errno (ERANGE);
382 else if (!matherr(&exc)) {
383 if (_LIB_VERSION == _SVID_) {
384 (void) WRITE2("lgamma: SING error\n", 19);
394 exc.name = CSTR ("log");
395 if (_LIB_VERSION == _SVID_)
398 exc.retval = -HUGE_VAL;
399 if (_LIB_VERSION == _POSIX_)
400 __set_errno (ERANGE);
401 else if (!matherr(&exc)) {
402 if (_LIB_VERSION == _SVID_) {
403 (void) WRITE2("log: SING error\n", 16);
413 exc.name = CSTR ("log");
414 if (_LIB_VERSION == _SVID_)
418 if (_LIB_VERSION == _POSIX_)
420 else if (!matherr(&exc)) {
421 if (_LIB_VERSION == _SVID_) {
422 (void) WRITE2("log: DOMAIN error\n", 18);
432 exc.name = CSTR ("log10");
433 if (_LIB_VERSION == _SVID_)
436 exc.retval = -HUGE_VAL;
437 if (_LIB_VERSION == _POSIX_)
438 __set_errno (ERANGE);
439 else if (!matherr(&exc)) {
440 if (_LIB_VERSION == _SVID_) {
441 (void) WRITE2("log10: SING error\n", 18);
451 exc.name = CSTR ("log10");
452 if (_LIB_VERSION == _SVID_)
456 if (_LIB_VERSION == _POSIX_)
458 else if (!matherr(&exc)) {
459 if (_LIB_VERSION == _SVID_) {
460 (void) WRITE2("log10: DOMAIN error\n", 20);
468 /* pow(x,y) overflow */
470 exc.name = CSTR ("pow");
471 if (_LIB_VERSION == _SVID_) {
474 if(x<zero&&rint(y)!=y) exc.retval = -HUGE;
476 exc.retval = HUGE_VAL;
478 if(x<zero&&rint(y)!=y) exc.retval = -HUGE_VAL;
480 if (_LIB_VERSION == _POSIX_)
481 __set_errno (ERANGE);
482 else if (!matherr(&exc)) {
483 __set_errno (ERANGE);
489 /* pow(x,y) underflow */
490 exc.type = UNDERFLOW;
491 exc.name = CSTR ("pow");
494 if (x < zero && rint (y) != y)
496 if (_LIB_VERSION == _POSIX_)
497 __set_errno (ERANGE);
498 else if (!matherr(&exc)) {
499 __set_errno (ERANGE);
507 exc.name = CSTR ("pow");
508 if (_LIB_VERSION == _SVID_)
511 exc.retval = -HUGE_VAL;
512 if (_LIB_VERSION == _POSIX_)
513 __set_errno (ERANGE);
514 else if (!matherr(&exc)) {
515 if (_LIB_VERSION == _SVID_) {
516 (void) WRITE2("pow(0,neg): DOMAIN error\n", 25);
526 exc.name = CSTR ("pow");
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);
543 /* neg**non-integral */
545 exc.name = CSTR ("pow");
546 if (_LIB_VERSION == _SVID_)
549 exc.retval = zero/zero; /* X/Open allow NaN */
550 if (_LIB_VERSION == _POSIX_)
552 else if (!matherr(&exc)) {
553 if (_LIB_VERSION == _SVID_) {
554 (void) WRITE2("neg**non-integral: DOMAIN error\n", 32);
562 /* sinh(finite) overflow */
564 exc.name = CSTR ("sinh");
565 if (_LIB_VERSION == _SVID_)
566 exc.retval = ( (x>zero) ? HUGE : -HUGE);
568 exc.retval = ( (x>zero) ? HUGE_VAL : -HUGE_VAL);
569 if (_LIB_VERSION == _POSIX_)
570 __set_errno (ERANGE);
571 else if (!matherr(&exc)) {
572 __set_errno (ERANGE);
580 exc.name = CSTR ("sqrt");
581 if (_LIB_VERSION == _SVID_)
584 exc.retval = zero/zero;
585 if (_LIB_VERSION == _POSIX_)
587 else if (!matherr(&exc)) {
588 if (_LIB_VERSION == _SVID_) {
589 (void) WRITE2("sqrt: DOMAIN error\n", 19);
599 exc.name = CSTR ("fmod");
600 if (_LIB_VERSION == _SVID_)
603 exc.retval = zero/zero;
604 if (_LIB_VERSION == _POSIX_)
606 else if (!matherr(&exc)) {
607 if (_LIB_VERSION == _SVID_) {
608 (void) WRITE2("fmod: DOMAIN error\n", 20);
618 exc.name = CSTR ("remainder");
619 exc.retval = zero/zero;
620 if (_LIB_VERSION == _POSIX_)
622 else if (!matherr(&exc)) {
623 if (_LIB_VERSION == _SVID_) {
624 (void) WRITE2("remainder: DOMAIN error\n", 24);
634 exc.name = CSTR ("acosh");
635 exc.retval = zero/zero;
636 if (_LIB_VERSION == _POSIX_)
638 else if (!matherr(&exc)) {
639 if (_LIB_VERSION == _SVID_) {
640 (void) WRITE2("acosh: DOMAIN error\n", 20);
650 exc.name = CSTR ("atanh");
651 exc.retval = zero/zero;
652 if (_LIB_VERSION == _POSIX_)
654 else if (!matherr(&exc)) {
655 if (_LIB_VERSION == _SVID_) {
656 (void) WRITE2("atanh: DOMAIN error\n", 20);
666 exc.name = CSTR ("atanh");
667 exc.retval = x/zero; /* sign(x)*inf */
668 if (_LIB_VERSION == _POSIX_)
669 __set_errno (ERANGE);
670 else if (!matherr(&exc)) {
671 if (_LIB_VERSION == _SVID_) {
672 (void) WRITE2("atanh: SING error\n", 18);
680 /* scalb overflow; SVID also returns +-HUGE_VAL */
682 exc.name = CSTR ("scalb");
683 exc.retval = x > zero ? HUGE_VAL : -HUGE_VAL;
684 if (_LIB_VERSION == _POSIX_)
685 __set_errno (ERANGE);
686 else if (!matherr(&exc)) {
687 __set_errno (ERANGE);
693 /* scalb underflow */
694 exc.type = UNDERFLOW;
695 exc.name = CSTR ("scalb");
696 exc.retval = copysign(zero,x);
697 if (_LIB_VERSION == _POSIX_)
698 __set_errno (ERANGE);
699 else if (!matherr(&exc)) {
700 __set_errno (ERANGE);
706 /* j0(|x|>X_TLOSS) */
708 exc.name = CSTR ("j0");
710 if (_LIB_VERSION == _POSIX_)
711 __set_errno (ERANGE);
712 else if (!matherr(&exc)) {
713 if (_LIB_VERSION == _SVID_) {
714 (void) WRITE2(exc.name, 2);
715 (void) WRITE2(": TLOSS error\n", 14);
717 __set_errno (ERANGE);
725 exc.name = CSTR ("y0");
727 if (_LIB_VERSION == _POSIX_)
728 __set_errno (ERANGE);
729 else if (!matherr(&exc)) {
730 if (_LIB_VERSION == _SVID_) {
731 (void) WRITE2(exc.name, 2);
732 (void) WRITE2(": TLOSS error\n", 14);
734 __set_errno (ERANGE);
740 /* j1(|x|>X_TLOSS) */
742 exc.name = CSTR ("j1");
744 if (_LIB_VERSION == _POSIX_)
745 __set_errno (ERANGE);
746 else if (!matherr(&exc)) {
747 if (_LIB_VERSION == _SVID_) {
748 (void) WRITE2(exc.name, 2);
749 (void) WRITE2(": TLOSS error\n", 14);
751 __set_errno (ERANGE);
759 exc.name = CSTR ("y1");
761 if (_LIB_VERSION == _POSIX_)
762 __set_errno (ERANGE);
763 else if (!matherr(&exc)) {
764 if (_LIB_VERSION == _SVID_) {
765 (void) WRITE2(exc.name, 2);
766 (void) WRITE2(": TLOSS error\n", 14);
768 __set_errno (ERANGE);
774 /* jn(|x|>X_TLOSS) */
776 exc.name = CSTR ("jn");
778 if (_LIB_VERSION == _POSIX_)
779 __set_errno (ERANGE);
780 else if (!matherr(&exc)) {
781 if (_LIB_VERSION == _SVID_) {
782 (void) WRITE2(exc.name, 2);
783 (void) WRITE2(": TLOSS error\n", 14);
785 __set_errno (ERANGE);
793 exc.name = CSTR ("yn");
795 if (_LIB_VERSION == _POSIX_)
796 __set_errno (ERANGE);
797 else if (!matherr(&exc)) {
798 if (_LIB_VERSION == _SVID_) {
799 (void) WRITE2(exc.name, 2);
800 (void) WRITE2(": TLOSS error\n", 14);
802 __set_errno (ERANGE);
808 /* tgamma(finite) overflow */
810 exc.name = CSTR ("tgamma");
811 exc.retval = copysign (HUGE_VAL, x);
812 if (_LIB_VERSION == _POSIX_)
813 __set_errno (ERANGE);
814 else if (!matherr(&exc)) {
815 __set_errno (ERANGE);
821 /* tgamma(-integer) */
823 exc.name = CSTR ("tgamma");
825 if (_LIB_VERSION == _POSIX_)
827 else if (!matherr(&exc)) {
828 if (_LIB_VERSION == _SVID_) {
829 (void) WRITE2("tgamma: SING error\n", 18);
830 exc.retval = HUGE_VAL;
839 /* exp(finite) overflow */
841 exc.name = CSTR ("exp2");
842 if (_LIB_VERSION == _SVID_)
845 exc.retval = HUGE_VAL;
846 if (_LIB_VERSION == _POSIX_)
847 __set_errno (ERANGE);
848 else if (!matherr(&exc)) {
849 __set_errno (ERANGE);
855 /* exp(finite) underflow */
856 exc.type = UNDERFLOW;
857 exc.name = CSTR ("exp2");
859 if (_LIB_VERSION == _POSIX_)
860 __set_errno (ERANGE);
861 else if (!matherr(&exc)) {
862 __set_errno (ERANGE);
869 /* exp(finite) overflow */
871 exc.name = CSTR ("exp10");
872 if (_LIB_VERSION == _SVID_)
875 exc.retval = HUGE_VAL;
876 if (_LIB_VERSION == _POSIX_)
877 __set_errno (ERANGE);
878 else if (!matherr(&exc)) {
879 __set_errno (ERANGE);
885 /* exp(finite) underflow */
886 exc.type = UNDERFLOW;
887 exc.name = CSTR ("exp10");
889 if (_LIB_VERSION == _POSIX_)
890 __set_errno (ERANGE);
891 else if (!matherr(&exc)) {
892 __set_errno (ERANGE);
900 exc.name = CSTR ("log2");
901 if (_LIB_VERSION == _SVID_)
904 exc.retval = -HUGE_VAL;
905 if (_LIB_VERSION == _POSIX_)
906 __set_errno (ERANGE);
907 else if (!matherr(&exc)) {
916 exc.name = CSTR ("log2");
917 if (_LIB_VERSION == _SVID_)
921 if (_LIB_VERSION == _POSIX_)
923 else if (!matherr(&exc)) {
932 exc.name = CSTR ("tgamma");
933 exc.retval = copysign (HUGE_VAL, x);
934 if (_LIB_VERSION == _POSIX_)
935 __set_errno (ERANGE);
936 else if (!matherr(&exc)) {
937 if (_LIB_VERSION == _SVID_)
938 (void) WRITE2("tgamma: SING error\n", 18);
939 __set_errno (ERANGE);
943 /* #### Last used is 50/150/250 ### */
946 __builtin_unreachable ();