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 ();