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 */
108 /* The SVID struct exception uses a field "char *name;". */
109 #define CSTR(func) ((char *) (type < 100 \
111 : (type < 200 ? func "f" : func "l")))
114 (void) fflush(stdout
);
124 exc
.name
= CSTR ("acos");
125 if (_LIB_VERSION
== _SVID_
)
129 if (_LIB_VERSION
== _POSIX_
)
131 else if (!matherr(&exc
)) {
132 if(_LIB_VERSION
== _SVID_
) {
133 (void) WRITE2("acos: DOMAIN error\n", 19);
143 exc
.name
= CSTR ("asin");
144 if (_LIB_VERSION
== _SVID_
)
148 if(_LIB_VERSION
== _POSIX_
)
150 else if (!matherr(&exc
)) {
151 if(_LIB_VERSION
== _SVID_
) {
152 (void) WRITE2("asin: DOMAIN error\n", 19);
164 exc
.name
= CSTR ("atan2");
165 assert (_LIB_VERSION
== _SVID_
);
167 if(_LIB_VERSION
== _POSIX_
)
169 else if (!matherr(&exc
)) {
170 if(_LIB_VERSION
== _SVID_
) {
171 (void) WRITE2("atan2: DOMAIN error\n", 20);
179 /* hypot(finite,finite) overflow */
181 exc
.name
= CSTR ("hypot");
182 if (_LIB_VERSION
== _SVID_
)
185 exc
.retval
= HUGE_VAL
;
186 if (_LIB_VERSION
== _POSIX_
)
187 __set_errno (ERANGE
);
188 else if (!matherr(&exc
)) {
189 __set_errno (ERANGE
);
195 /* cosh(finite) overflow */
197 exc
.name
= CSTR ("cosh");
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
= CSTR ("exp");
214 if (_LIB_VERSION
== _SVID_
)
217 exc
.retval
= HUGE_VAL
;
218 if (_LIB_VERSION
== _POSIX_
)
219 __set_errno (ERANGE
);
220 else if (!matherr(&exc
)) {
221 __set_errno (ERANGE
);
227 /* exp(finite) underflow */
228 exc
.type
= UNDERFLOW
;
229 exc
.name
= CSTR ("exp");
231 if (_LIB_VERSION
== _POSIX_
)
232 __set_errno (ERANGE
);
233 else if (!matherr(&exc
)) {
234 __set_errno (ERANGE
);
241 exc
.type
= DOMAIN
; /* should be SING for IEEE */
242 exc
.name
= CSTR ("y0");
243 if (_LIB_VERSION
== _SVID_
)
246 exc
.retval
= -HUGE_VAL
;
247 if (_LIB_VERSION
== _POSIX_
)
248 __set_errno (ERANGE
);
249 else if (!matherr(&exc
)) {
250 if (_LIB_VERSION
== _SVID_
) {
251 (void) WRITE2("y0: DOMAIN error\n", 17);
261 exc
.name
= CSTR ("y0");
262 if (_LIB_VERSION
== _SVID_
)
266 if (_LIB_VERSION
== _POSIX_
)
268 else if (!matherr(&exc
)) {
269 if (_LIB_VERSION
== _SVID_
) {
270 (void) WRITE2("y0: DOMAIN error\n", 17);
279 exc
.type
= DOMAIN
; /* should be SING for IEEE */
280 exc
.name
= CSTR ("y1");
281 if (_LIB_VERSION
== _SVID_
)
284 exc
.retval
= -HUGE_VAL
;
285 if (_LIB_VERSION
== _POSIX_
)
286 __set_errno (ERANGE
);
287 else if (!matherr(&exc
)) {
288 if (_LIB_VERSION
== _SVID_
) {
289 (void) WRITE2("y1: DOMAIN error\n", 17);
299 exc
.name
= CSTR ("y1");
300 if (_LIB_VERSION
== _SVID_
)
304 if (_LIB_VERSION
== _POSIX_
)
306 else if (!matherr(&exc
)) {
307 if (_LIB_VERSION
== _SVID_
) {
308 (void) WRITE2("y1: DOMAIN error\n", 17);
317 exc
.type
= DOMAIN
; /* should be SING for IEEE */
318 exc
.name
= CSTR ("yn");
319 if (_LIB_VERSION
== _SVID_
)
322 exc
.retval
= ((x
< 0 && ((int) x
& 1) != 0)
325 if (_LIB_VERSION
== _POSIX_
)
326 __set_errno (ERANGE
);
327 else if (!matherr(&exc
)) {
328 if (_LIB_VERSION
== _SVID_
) {
329 (void) WRITE2("yn: DOMAIN error\n", 17);
339 exc
.name
= CSTR ("yn");
340 if (_LIB_VERSION
== _SVID_
)
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
= CSTR ("lgamma");
359 if (_LIB_VERSION
== _SVID_
)
362 exc
.retval
= HUGE_VAL
;
363 if (_LIB_VERSION
== _POSIX_
)
364 __set_errno (ERANGE
);
365 else if (!matherr(&exc
)) {
366 __set_errno (ERANGE
);
372 /* lgamma(-integer) or lgamma(0) */
374 exc
.name
= CSTR ("lgamma");
375 if (_LIB_VERSION
== _SVID_
)
378 exc
.retval
= HUGE_VAL
;
379 if (_LIB_VERSION
== _POSIX_
)
380 __set_errno (ERANGE
);
381 else if (!matherr(&exc
)) {
382 if (_LIB_VERSION
== _SVID_
) {
383 (void) WRITE2("lgamma: SING error\n", 19);
393 exc
.name
= CSTR ("log");
394 if (_LIB_VERSION
== _SVID_
)
397 exc
.retval
= -HUGE_VAL
;
398 if (_LIB_VERSION
== _POSIX_
)
399 __set_errno (ERANGE
);
400 else if (!matherr(&exc
)) {
401 if (_LIB_VERSION
== _SVID_
) {
402 (void) WRITE2("log: SING error\n", 16);
412 exc
.name
= CSTR ("log");
413 if (_LIB_VERSION
== _SVID_
)
417 if (_LIB_VERSION
== _POSIX_
)
419 else if (!matherr(&exc
)) {
420 if (_LIB_VERSION
== _SVID_
) {
421 (void) WRITE2("log: DOMAIN error\n", 18);
431 exc
.name
= CSTR ("log10");
432 if (_LIB_VERSION
== _SVID_
)
435 exc
.retval
= -HUGE_VAL
;
436 if (_LIB_VERSION
== _POSIX_
)
437 __set_errno (ERANGE
);
438 else if (!matherr(&exc
)) {
439 if (_LIB_VERSION
== _SVID_
) {
440 (void) WRITE2("log10: SING error\n", 18);
450 exc
.name
= CSTR ("log10");
451 if (_LIB_VERSION
== _SVID_
)
455 if (_LIB_VERSION
== _POSIX_
)
457 else if (!matherr(&exc
)) {
458 if (_LIB_VERSION
== _SVID_
) {
459 (void) WRITE2("log10: DOMAIN error\n", 20);
468 /* error only if _LIB_VERSION == _SVID_ */
470 exc
.name
= CSTR ("pow");
472 if (_LIB_VERSION
!= _SVID_
) exc
.retval
= 1.0;
473 else if (!matherr(&exc
)) {
474 (void) WRITE2("pow(0,0): DOMAIN error\n", 23);
481 /* pow(x,y) overflow */
483 exc
.name
= CSTR ("pow");
484 if (_LIB_VERSION
== _SVID_
) {
487 if(x
<zero
&&__rint(y
)!=y
) exc
.retval
= -HUGE
;
489 exc
.retval
= HUGE_VAL
;
491 if(x
<zero
&&__rint(y
)!=y
) exc
.retval
= -HUGE_VAL
;
493 if (_LIB_VERSION
== _POSIX_
)
494 __set_errno (ERANGE
);
495 else if (!matherr(&exc
)) {
496 __set_errno (ERANGE
);
502 /* pow(x,y) underflow */
503 exc
.type
= UNDERFLOW
;
504 exc
.name
= CSTR ("pow");
507 if (x
< zero
&& __rint (y
) != y
)
509 if (_LIB_VERSION
== _POSIX_
)
510 __set_errno (ERANGE
);
511 else if (!matherr(&exc
)) {
512 __set_errno (ERANGE
);
520 exc
.name
= CSTR ("pow");
521 if (_LIB_VERSION
== _SVID_
)
524 exc
.retval
= -HUGE_VAL
;
525 if (_LIB_VERSION
== _POSIX_
)
526 __set_errno (ERANGE
);
527 else if (!matherr(&exc
)) {
528 if (_LIB_VERSION
== _SVID_
) {
529 (void) WRITE2("pow(0,neg): DOMAIN error\n", 25);
539 exc
.name
= CSTR ("pow");
540 if (_LIB_VERSION
== _SVID_
)
543 exc
.retval
= HUGE_VAL
;
544 if (_LIB_VERSION
== _POSIX_
)
545 __set_errno (ERANGE
);
546 else if (!matherr(&exc
)) {
547 if (_LIB_VERSION
== _SVID_
) {
548 (void) WRITE2("pow(0,neg): DOMAIN error\n", 25);
556 /* neg**non-integral */
558 exc
.name
= CSTR ("pow");
559 if (_LIB_VERSION
== _SVID_
)
562 exc
.retval
= zero
/zero
; /* X/Open allow NaN */
563 if (_LIB_VERSION
== _POSIX_
)
565 else if (!matherr(&exc
)) {
566 if (_LIB_VERSION
== _SVID_
) {
567 (void) WRITE2("neg**non-integral: DOMAIN error\n", 32);
575 /* sinh(finite) overflow */
577 exc
.name
= CSTR ("sinh");
578 if (_LIB_VERSION
== _SVID_
)
579 exc
.retval
= ( (x
>zero
) ? HUGE
: -HUGE
);
581 exc
.retval
= ( (x
>zero
) ? HUGE_VAL
: -HUGE_VAL
);
582 if (_LIB_VERSION
== _POSIX_
)
583 __set_errno (ERANGE
);
584 else if (!matherr(&exc
)) {
585 __set_errno (ERANGE
);
593 exc
.name
= CSTR ("sqrt");
594 if (_LIB_VERSION
== _SVID_
)
597 exc
.retval
= zero
/zero
;
598 if (_LIB_VERSION
== _POSIX_
)
600 else if (!matherr(&exc
)) {
601 if (_LIB_VERSION
== _SVID_
) {
602 (void) WRITE2("sqrt: DOMAIN error\n", 19);
612 exc
.name
= CSTR ("fmod");
613 if (_LIB_VERSION
== _SVID_
)
616 exc
.retval
= zero
/zero
;
617 if (_LIB_VERSION
== _POSIX_
)
619 else if (!matherr(&exc
)) {
620 if (_LIB_VERSION
== _SVID_
) {
621 (void) WRITE2("fmod: DOMAIN error\n", 20);
631 exc
.name
= CSTR ("remainder");
632 exc
.retval
= zero
/zero
;
633 if (_LIB_VERSION
== _POSIX_
)
635 else if (!matherr(&exc
)) {
636 if (_LIB_VERSION
== _SVID_
) {
637 (void) WRITE2("remainder: DOMAIN error\n", 24);
647 exc
.name
= CSTR ("acosh");
648 exc
.retval
= zero
/zero
;
649 if (_LIB_VERSION
== _POSIX_
)
651 else if (!matherr(&exc
)) {
652 if (_LIB_VERSION
== _SVID_
) {
653 (void) WRITE2("acosh: DOMAIN error\n", 20);
663 exc
.name
= CSTR ("atanh");
664 exc
.retval
= zero
/zero
;
665 if (_LIB_VERSION
== _POSIX_
)
667 else if (!matherr(&exc
)) {
668 if (_LIB_VERSION
== _SVID_
) {
669 (void) WRITE2("atanh: DOMAIN error\n", 20);
679 exc
.name
= CSTR ("atanh");
680 exc
.retval
= x
/zero
; /* sign(x)*inf */
681 if (_LIB_VERSION
== _POSIX_
)
682 __set_errno (ERANGE
);
683 else if (!matherr(&exc
)) {
684 if (_LIB_VERSION
== _SVID_
) {
685 (void) WRITE2("atanh: SING error\n", 18);
693 /* scalb overflow; SVID also returns +-HUGE_VAL */
695 exc
.name
= CSTR ("scalb");
696 exc
.retval
= x
> zero
? HUGE_VAL
: -HUGE_VAL
;
697 if (_LIB_VERSION
== _POSIX_
)
698 __set_errno (ERANGE
);
699 else if (!matherr(&exc
)) {
700 __set_errno (ERANGE
);
706 /* scalb underflow */
707 exc
.type
= UNDERFLOW
;
708 exc
.name
= CSTR ("scalb");
709 exc
.retval
= __copysign(zero
,x
);
710 if (_LIB_VERSION
== _POSIX_
)
711 __set_errno (ERANGE
);
712 else if (!matherr(&exc
)) {
713 __set_errno (ERANGE
);
719 /* j0(|x|>X_TLOSS) */
721 exc
.name
= CSTR ("j0");
723 if (_LIB_VERSION
== _POSIX_
)
724 __set_errno (ERANGE
);
725 else if (!matherr(&exc
)) {
726 if (_LIB_VERSION
== _SVID_
) {
727 (void) WRITE2(exc
.name
, 2);
728 (void) WRITE2(": TLOSS error\n", 14);
730 __set_errno (ERANGE
);
738 exc
.name
= CSTR ("y0");
740 if (_LIB_VERSION
== _POSIX_
)
741 __set_errno (ERANGE
);
742 else if (!matherr(&exc
)) {
743 if (_LIB_VERSION
== _SVID_
) {
744 (void) WRITE2(exc
.name
, 2);
745 (void) WRITE2(": TLOSS error\n", 14);
747 __set_errno (ERANGE
);
753 /* j1(|x|>X_TLOSS) */
755 exc
.name
= CSTR ("j1");
757 if (_LIB_VERSION
== _POSIX_
)
758 __set_errno (ERANGE
);
759 else if (!matherr(&exc
)) {
760 if (_LIB_VERSION
== _SVID_
) {
761 (void) WRITE2(exc
.name
, 2);
762 (void) WRITE2(": TLOSS error\n", 14);
764 __set_errno (ERANGE
);
772 exc
.name
= CSTR ("y1");
774 if (_LIB_VERSION
== _POSIX_
)
775 __set_errno (ERANGE
);
776 else if (!matherr(&exc
)) {
777 if (_LIB_VERSION
== _SVID_
) {
778 (void) WRITE2(exc
.name
, 2);
779 (void) WRITE2(": TLOSS error\n", 14);
781 __set_errno (ERANGE
);
787 /* jn(|x|>X_TLOSS) */
789 exc
.name
= CSTR ("jn");
791 if (_LIB_VERSION
== _POSIX_
)
792 __set_errno (ERANGE
);
793 else if (!matherr(&exc
)) {
794 if (_LIB_VERSION
== _SVID_
) {
795 (void) WRITE2(exc
.name
, 2);
796 (void) WRITE2(": TLOSS error\n", 14);
798 __set_errno (ERANGE
);
806 exc
.name
= CSTR ("yn");
808 if (_LIB_VERSION
== _POSIX_
)
809 __set_errno (ERANGE
);
810 else if (!matherr(&exc
)) {
811 if (_LIB_VERSION
== _SVID_
) {
812 (void) WRITE2(exc
.name
, 2);
813 (void) WRITE2(": TLOSS error\n", 14);
815 __set_errno (ERANGE
);
821 /* tgamma(finite) overflow */
823 exc
.name
= CSTR ("tgamma");
824 exc
.retval
= __copysign (HUGE_VAL
, x
);
825 if (_LIB_VERSION
== _POSIX_
)
826 __set_errno (ERANGE
);
827 else if (!matherr(&exc
)) {
828 __set_errno (ERANGE
);
834 /* tgamma(-integer) */
836 exc
.name
= CSTR ("tgamma");
838 if (_LIB_VERSION
== _POSIX_
)
840 else if (!matherr(&exc
)) {
841 if (_LIB_VERSION
== _SVID_
) {
842 (void) WRITE2("tgamma: SING error\n", 18);
843 exc
.retval
= HUGE_VAL
;
852 /* error only if _LIB_VERSION == _SVID_ & _XOPEN_ */
854 exc
.name
= CSTR ("pow");
856 if (_LIB_VERSION
== _IEEE_
||
857 _LIB_VERSION
== _POSIX_
) exc
.retval
= 1.0;
858 else if (!matherr(&exc
)) {
866 /* exp(finite) overflow */
868 exc
.name
= CSTR ("exp2");
869 if (_LIB_VERSION
== _SVID_
)
872 exc
.retval
= HUGE_VAL
;
873 if (_LIB_VERSION
== _POSIX_
)
874 __set_errno (ERANGE
);
875 else if (!matherr(&exc
)) {
876 __set_errno (ERANGE
);
882 /* exp(finite) underflow */
883 exc
.type
= UNDERFLOW
;
884 exc
.name
= CSTR ("exp2");
886 if (_LIB_VERSION
== _POSIX_
)
887 __set_errno (ERANGE
);
888 else if (!matherr(&exc
)) {
889 __set_errno (ERANGE
);
896 /* exp(finite) overflow */
898 exc
.name
= CSTR ("exp10");
899 if (_LIB_VERSION
== _SVID_
)
902 exc
.retval
= HUGE_VAL
;
903 if (_LIB_VERSION
== _POSIX_
)
904 __set_errno (ERANGE
);
905 else if (!matherr(&exc
)) {
906 __set_errno (ERANGE
);
912 /* exp(finite) underflow */
913 exc
.type
= UNDERFLOW
;
914 exc
.name
= CSTR ("exp10");
916 if (_LIB_VERSION
== _POSIX_
)
917 __set_errno (ERANGE
);
918 else if (!matherr(&exc
)) {
919 __set_errno (ERANGE
);
927 exc
.name
= CSTR ("log2");
928 if (_LIB_VERSION
== _SVID_
)
931 exc
.retval
= -HUGE_VAL
;
932 if (_LIB_VERSION
== _POSIX_
)
933 __set_errno (ERANGE
);
934 else if (!matherr(&exc
)) {
943 exc
.name
= CSTR ("log2");
944 if (_LIB_VERSION
== _SVID_
)
948 if (_LIB_VERSION
== _POSIX_
)
950 else if (!matherr(&exc
)) {
959 exc
.name
= CSTR ("tgamma");
960 exc
.retval
= __copysign (HUGE_VAL
, x
);
961 if (_LIB_VERSION
== _POSIX_
)
962 __set_errno (ERANGE
);
963 else if (!matherr(&exc
)) {
964 if (_LIB_VERSION
== _SVID_
)
965 (void) WRITE2("tgamma: SING error\n", 18);
966 __set_errno (ERANGE
);
970 /* #### Last used is 50/150/250 ### */