uc-sdk
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
k_standard.c
Go to the documentation of this file.
1 
2 /* @(#)k_standard.c 1.3 95/01/18 */
3 /*
4  * ====================================================
5  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
6  *
7  * Developed at SunSoft, a Sun Microsystems, Inc. business.
8  * Permission to use, copy, modify, and distribute this
9  * software is freely granted, provided that this notice
10  * is preserved.
11  * ====================================================
12  *
13  */
14 
15 #include "fdlibm.h"
16 #include <errno.h>
17 
18 #ifndef _USE_WRITE
19 #include <stdio.h> /* fputs(), stderr */
20 #define WRITE2(u,v) fputs(u, stderr)
21 #else /* !defined(_USE_WRITE) */
22 #include <unistd.h> /* write */
23 #define WRITE2(u,v) write(2, u, v)
24 #undef fflush
25 #endif /* !defined(_USE_WRITE) */
26 
27 static double zero = 0.0; /* used as const */
28 
29 /*
30  * Standard conformance (non-IEEE) on exception cases.
31  * Mapping:
32  * 1 -- acos(|x|>1)
33  * 2 -- asin(|x|>1)
34  * 3 -- atan2(+-0,+-0)
35  * 4 -- hypot overflow
36  * 5 -- cosh overflow
37  * 6 -- exp overflow
38  * 7 -- exp underflow
39  * 8 -- y0(0)
40  * 9 -- y0(-ve)
41  * 10-- y1(0)
42  * 11-- y1(-ve)
43  * 12-- yn(0)
44  * 13-- yn(-ve)
45  * 14-- lgamma(finite) overflow
46  * 15-- lgamma(-integer)
47  * 16-- log(0)
48  * 17-- log(x<0)
49  * 18-- log10(0)
50  * 19-- log10(x<0)
51  * 20-- pow(0.0,0.0)
52  * 21-- pow(x,y) overflow
53  * 22-- pow(x,y) underflow
54  * 23-- pow(0,negative)
55  * 24-- pow(neg,non-integral)
56  * 25-- sinh(finite) overflow
57  * 26-- sqrt(negative)
58  * 27-- fmod(x,0)
59  * 28-- remainder(x,0)
60  * 29-- acosh(x<1)
61  * 30-- atanh(|x|>1)
62  * 31-- atanh(|x|=1)
63  * 32-- scalb overflow
64  * 33-- scalb underflow
65  * 34-- j0(|x|>X_TLOSS)
66  * 35-- y0(x>X_TLOSS)
67  * 36-- j1(|x|>X_TLOSS)
68  * 37-- y1(x>X_TLOSS)
69  * 38-- jn(|x|>X_TLOSS, n)
70  * 39-- yn(x>X_TLOSS, n)
71  * 40-- gamma(finite) overflow
72  * 41-- gamma(-integer)
73  * 42-- pow(NaN,0.0)
74  */
75 
76 
77 #ifdef __STDC__
78  double __kernel_standard(double x, double y, int type)
79 #else
80  double __kernel_standard(x,y,type)
81  double x,y; int type;
82 #endif
83 {
84  struct exception exc;
85 #ifndef HUGE_VAL /* this is the only routine that uses HUGE_VAL */
86 #define HUGE_VAL inf
87  double inf = 0.0;
88 
89  __HI(inf) = 0x7ff00000; /* set inf to infinite */
90 #endif
91 
92 #ifdef _USE_WRITE
93  (void) fflush(stdout);
94 #endif
95  exc.arg1 = x;
96  exc.arg2 = y;
97  switch(type) {
98  case 1:
99  /* acos(|x|>1) */
100  exc.type = DOMAIN;
101  exc.name = "acos";
102  exc.retval = zero;
103  if (_LIB_VERSION == _POSIX_)
104  errno = EDOM;
105  else if (!matherr(&exc)) {
106  if(_LIB_VERSION == _SVID_) {
107  (void) WRITE2("acos: DOMAIN error\n", 19);
108  }
109  errno = EDOM;
110  }
111  break;
112  case 2:
113  /* asin(|x|>1) */
114  exc.type = DOMAIN;
115  exc.name = "asin";
116  exc.retval = zero;
117  if(_LIB_VERSION == _POSIX_)
118  errno = EDOM;
119  else if (!matherr(&exc)) {
120  if(_LIB_VERSION == _SVID_) {
121  (void) WRITE2("asin: DOMAIN error\n", 19);
122  }
123  errno = EDOM;
124  }
125  break;
126  case 3:
127  /* atan2(+-0,+-0) */
128  exc.arg1 = y;
129  exc.arg2 = x;
130  exc.type = DOMAIN;
131  exc.name = "atan2";
132  exc.retval = zero;
133  if(_LIB_VERSION == _POSIX_)
134  errno = EDOM;
135  else if (!matherr(&exc)) {
136  if(_LIB_VERSION == _SVID_) {
137  (void) WRITE2("atan2: DOMAIN error\n", 20);
138  }
139  errno = EDOM;
140  }
141  break;
142  case 4:
143  /* hypot(finite,finite) overflow */
144  exc.type = OVERFLOW;
145  exc.name = "hypot";
146  if (_LIB_VERSION == _SVID_)
147  exc.retval = HUGE;
148  else
149  exc.retval = HUGE_VAL;
150  if (_LIB_VERSION == _POSIX_)
151  errno = ERANGE;
152  else if (!matherr(&exc)) {
153  errno = ERANGE;
154  }
155  break;
156  case 5:
157  /* cosh(finite) overflow */
158  exc.type = OVERFLOW;
159  exc.name = "cosh";
160  if (_LIB_VERSION == _SVID_)
161  exc.retval = HUGE;
162  else
163  exc.retval = HUGE_VAL;
164  if (_LIB_VERSION == _POSIX_)
165  errno = ERANGE;
166  else if (!matherr(&exc)) {
167  errno = ERANGE;
168  }
169  break;
170  case 6:
171  /* exp(finite) overflow */
172  exc.type = OVERFLOW;
173  exc.name = "exp";
174  if (_LIB_VERSION == _SVID_)
175  exc.retval = HUGE;
176  else
177  exc.retval = HUGE_VAL;
178  if (_LIB_VERSION == _POSIX_)
179  errno = ERANGE;
180  else if (!matherr(&exc)) {
181  errno = ERANGE;
182  }
183  break;
184  case 7:
185  /* exp(finite) underflow */
186  exc.type = UNDERFLOW;
187  exc.name = "exp";
188  exc.retval = zero;
189  if (_LIB_VERSION == _POSIX_)
190  errno = ERANGE;
191  else if (!matherr(&exc)) {
192  errno = ERANGE;
193  }
194  break;
195  case 8:
196  /* y0(0) = -inf */
197  exc.type = DOMAIN; /* should be SING for IEEE */
198  exc.name = "y0";
199  if (_LIB_VERSION == _SVID_)
200  exc.retval = -HUGE;
201  else
202  exc.retval = -HUGE_VAL;
203  if (_LIB_VERSION == _POSIX_)
204  errno = EDOM;
205  else if (!matherr(&exc)) {
206  if (_LIB_VERSION == _SVID_) {
207  (void) WRITE2("y0: DOMAIN error\n", 17);
208  }
209  errno = EDOM;
210  }
211  break;
212  case 9:
213  /* y0(x<0) = NaN */
214  exc.type = DOMAIN;
215  exc.name = "y0";
216  if (_LIB_VERSION == _SVID_)
217  exc.retval = -HUGE;
218  else
219  exc.retval = -HUGE_VAL;
220  if (_LIB_VERSION == _POSIX_)
221  errno = EDOM;
222  else if (!matherr(&exc)) {
223  if (_LIB_VERSION == _SVID_) {
224  (void) WRITE2("y0: DOMAIN error\n", 17);
225  }
226  errno = EDOM;
227  }
228  break;
229  case 10:
230  /* y1(0) = -inf */
231  exc.type = DOMAIN; /* should be SING for IEEE */
232  exc.name = "y1";
233  if (_LIB_VERSION == _SVID_)
234  exc.retval = -HUGE;
235  else
236  exc.retval = -HUGE_VAL;
237  if (_LIB_VERSION == _POSIX_)
238  errno = EDOM;
239  else if (!matherr(&exc)) {
240  if (_LIB_VERSION == _SVID_) {
241  (void) WRITE2("y1: DOMAIN error\n", 17);
242  }
243  errno = EDOM;
244  }
245  break;
246  case 11:
247  /* y1(x<0) = NaN */
248  exc.type = DOMAIN;
249  exc.name = "y1";
250  if (_LIB_VERSION == _SVID_)
251  exc.retval = -HUGE;
252  else
253  exc.retval = -HUGE_VAL;
254  if (_LIB_VERSION == _POSIX_)
255  errno = EDOM;
256  else if (!matherr(&exc)) {
257  if (_LIB_VERSION == _SVID_) {
258  (void) WRITE2("y1: DOMAIN error\n", 17);
259  }
260  errno = EDOM;
261  }
262  break;
263  case 12:
264  /* yn(n,0) = -inf */
265  exc.type = DOMAIN; /* should be SING for IEEE */
266  exc.name = "yn";
267  if (_LIB_VERSION == _SVID_)
268  exc.retval = -HUGE;
269  else
270  exc.retval = -HUGE_VAL;
271  if (_LIB_VERSION == _POSIX_)
272  errno = EDOM;
273  else if (!matherr(&exc)) {
274  if (_LIB_VERSION == _SVID_) {
275  (void) WRITE2("yn: DOMAIN error\n", 17);
276  }
277  errno = EDOM;
278  }
279  break;
280  case 13:
281  /* yn(x<0) = NaN */
282  exc.type = DOMAIN;
283  exc.name = "yn";
284  if (_LIB_VERSION == _SVID_)
285  exc.retval = -HUGE;
286  else
287  exc.retval = -HUGE_VAL;
288  if (_LIB_VERSION == _POSIX_)
289  errno = EDOM;
290  else if (!matherr(&exc)) {
291  if (_LIB_VERSION == _SVID_) {
292  (void) WRITE2("yn: DOMAIN error\n", 17);
293  }
294  errno = EDOM;
295  }
296  break;
297  case 14:
298  /* lgamma(finite) overflow */
299  exc.type = OVERFLOW;
300  exc.name = "lgamma";
301  if (_LIB_VERSION == _SVID_)
302  exc.retval = HUGE;
303  else
304  exc.retval = HUGE_VAL;
305  if (_LIB_VERSION == _POSIX_)
306  errno = ERANGE;
307  else if (!matherr(&exc)) {
308  errno = ERANGE;
309  }
310  break;
311  case 15:
312  /* lgamma(-integer) or lgamma(0) */
313  exc.type = SING;
314  exc.name = "lgamma";
315  if (_LIB_VERSION == _SVID_)
316  exc.retval = HUGE;
317  else
318  exc.retval = HUGE_VAL;
319  if (_LIB_VERSION == _POSIX_)
320  errno = EDOM;
321  else if (!matherr(&exc)) {
322  if (_LIB_VERSION == _SVID_) {
323  (void) WRITE2("lgamma: SING error\n", 19);
324  }
325  errno = EDOM;
326  }
327  break;
328  case 16:
329  /* log(0) */
330  exc.type = SING;
331  exc.name = "log";
332  if (_LIB_VERSION == _SVID_)
333  exc.retval = -HUGE;
334  else
335  exc.retval = -HUGE_VAL;
336  if (_LIB_VERSION == _POSIX_)
337  errno = ERANGE;
338  else if (!matherr(&exc)) {
339  if (_LIB_VERSION == _SVID_) {
340  (void) WRITE2("log: SING error\n", 16);
341  }
342  errno = EDOM;
343  }
344  break;
345  case 17:
346  /* log(x<0) */
347  exc.type = DOMAIN;
348  exc.name = "log";
349  if (_LIB_VERSION == _SVID_)
350  exc.retval = -HUGE;
351  else
352  exc.retval = -HUGE_VAL;
353  if (_LIB_VERSION == _POSIX_)
354  errno = EDOM;
355  else if (!matherr(&exc)) {
356  if (_LIB_VERSION == _SVID_) {
357  (void) WRITE2("log: DOMAIN error\n", 18);
358  }
359  errno = EDOM;
360  }
361  break;
362  case 18:
363  /* log10(0) */
364  exc.type = SING;
365  exc.name = "log10";
366  if (_LIB_VERSION == _SVID_)
367  exc.retval = -HUGE;
368  else
369  exc.retval = -HUGE_VAL;
370  if (_LIB_VERSION == _POSIX_)
371  errno = ERANGE;
372  else if (!matherr(&exc)) {
373  if (_LIB_VERSION == _SVID_) {
374  (void) WRITE2("log10: SING error\n", 18);
375  }
376  errno = EDOM;
377  }
378  break;
379  case 19:
380  /* log10(x<0) */
381  exc.type = DOMAIN;
382  exc.name = "log10";
383  if (_LIB_VERSION == _SVID_)
384  exc.retval = -HUGE;
385  else
386  exc.retval = -HUGE_VAL;
387  if (_LIB_VERSION == _POSIX_)
388  errno = EDOM;
389  else if (!matherr(&exc)) {
390  if (_LIB_VERSION == _SVID_) {
391  (void) WRITE2("log10: DOMAIN error\n", 20);
392  }
393  errno = EDOM;
394  }
395  break;
396  case 20:
397  /* pow(0.0,0.0) */
398  /* error only if _LIB_VERSION == _SVID_ */
399  exc.type = DOMAIN;
400  exc.name = "pow";
401  exc.retval = zero;
402  if (_LIB_VERSION != _SVID_) exc.retval = 1.0;
403  else if (!matherr(&exc)) {
404  (void) WRITE2("pow(0,0): DOMAIN error\n", 23);
405  errno = EDOM;
406  }
407  break;
408  case 21:
409  /* pow(x,y) overflow */
410  exc.type = OVERFLOW;
411  exc.name = "pow";
412  if (_LIB_VERSION == _SVID_) {
413  exc.retval = HUGE;
414  y *= 0.5;
415  if(x<zero&&rint(y)!=y) exc.retval = -HUGE;
416  } else {
417  exc.retval = HUGE_VAL;
418  y *= 0.5;
419  if(x<zero&&rint(y)!=y) exc.retval = -HUGE_VAL;
420  }
421  if (_LIB_VERSION == _POSIX_)
422  errno = ERANGE;
423  else if (!matherr(&exc)) {
424  errno = ERANGE;
425  }
426  break;
427  case 22:
428  /* pow(x,y) underflow */
429  exc.type = UNDERFLOW;
430  exc.name = "pow";
431  exc.retval = zero;
432  if (_LIB_VERSION == _POSIX_)
433  errno = ERANGE;
434  else if (!matherr(&exc)) {
435  errno = ERANGE;
436  }
437  break;
438  case 23:
439  /* 0**neg */
440  exc.type = DOMAIN;
441  exc.name = "pow";
442  if (_LIB_VERSION == _SVID_)
443  exc.retval = zero;
444  else
445  exc.retval = -HUGE_VAL;
446  if (_LIB_VERSION == _POSIX_)
447  errno = EDOM;
448  else if (!matherr(&exc)) {
449  if (_LIB_VERSION == _SVID_) {
450  (void) WRITE2("pow(0,neg): DOMAIN error\n", 25);
451  }
452  errno = EDOM;
453  }
454  break;
455  case 24:
456  /* neg**non-integral */
457  exc.type = DOMAIN;
458  exc.name = "pow";
459  if (_LIB_VERSION == _SVID_)
460  exc.retval = zero;
461  else
462  exc.retval = zero/zero; /* X/Open allow NaN */
463  if (_LIB_VERSION == _POSIX_)
464  errno = EDOM;
465  else if (!matherr(&exc)) {
466  if (_LIB_VERSION == _SVID_) {
467  (void) WRITE2("neg**non-integral: DOMAIN error\n", 32);
468  }
469  errno = EDOM;
470  }
471  break;
472  case 25:
473  /* sinh(finite) overflow */
474  exc.type = OVERFLOW;
475  exc.name = "sinh";
476  if (_LIB_VERSION == _SVID_)
477  exc.retval = ( (x>zero) ? HUGE : -HUGE);
478  else
479  exc.retval = ( (x>zero) ? HUGE_VAL : -HUGE_VAL);
480  if (_LIB_VERSION == _POSIX_)
481  errno = ERANGE;
482  else if (!matherr(&exc)) {
483  errno = ERANGE;
484  }
485  break;
486  case 26:
487  /* sqrt(x<0) */
488  exc.type = DOMAIN;
489  exc.name = "sqrt";
490  if (_LIB_VERSION == _SVID_)
491  exc.retval = zero;
492  else
493  exc.retval = zero/zero;
494  if (_LIB_VERSION == _POSIX_)
495  errno = EDOM;
496  else if (!matherr(&exc)) {
497  if (_LIB_VERSION == _SVID_) {
498  (void) WRITE2("sqrt: DOMAIN error\n", 19);
499  }
500  errno = EDOM;
501  }
502  break;
503  case 27:
504  /* fmod(x,0) */
505  exc.type = DOMAIN;
506  exc.name = "fmod";
507  if (_LIB_VERSION == _SVID_)
508  exc.retval = x;
509  else
510  exc.retval = zero/zero;
511  if (_LIB_VERSION == _POSIX_)
512  errno = EDOM;
513  else if (!matherr(&exc)) {
514  if (_LIB_VERSION == _SVID_) {
515  (void) WRITE2("fmod: DOMAIN error\n", 20);
516  }
517  errno = EDOM;
518  }
519  break;
520  case 28:
521  /* remainder(x,0) */
522  exc.type = DOMAIN;
523  exc.name = "remainder";
524  exc.retval = zero/zero;
525  if (_LIB_VERSION == _POSIX_)
526  errno = EDOM;
527  else if (!matherr(&exc)) {
528  if (_LIB_VERSION == _SVID_) {
529  (void) WRITE2("remainder: DOMAIN error\n", 24);
530  }
531  errno = EDOM;
532  }
533  break;
534  case 29:
535  /* acosh(x<1) */
536  exc.type = DOMAIN;
537  exc.name = "acosh";
538  exc.retval = zero/zero;
539  if (_LIB_VERSION == _POSIX_)
540  errno = EDOM;
541  else if (!matherr(&exc)) {
542  if (_LIB_VERSION == _SVID_) {
543  (void) WRITE2("acosh: DOMAIN error\n", 20);
544  }
545  errno = EDOM;
546  }
547  break;
548  case 30:
549  /* atanh(|x|>1) */
550  exc.type = DOMAIN;
551  exc.name = "atanh";
552  exc.retval = zero/zero;
553  if (_LIB_VERSION == _POSIX_)
554  errno = EDOM;
555  else if (!matherr(&exc)) {
556  if (_LIB_VERSION == _SVID_) {
557  (void) WRITE2("atanh: DOMAIN error\n", 20);
558  }
559  errno = EDOM;
560  }
561  break;
562  case 31:
563  /* atanh(|x|=1) */
564  exc.type = SING;
565  exc.name = "atanh";
566  exc.retval = x/zero; /* sign(x)*inf */
567  if (_LIB_VERSION == _POSIX_)
568  errno = EDOM;
569  else if (!matherr(&exc)) {
570  if (_LIB_VERSION == _SVID_) {
571  (void) WRITE2("atanh: SING error\n", 18);
572  }
573  errno = EDOM;
574  }
575  break;
576  case 32:
577  /* scalb overflow; SVID also returns +-HUGE_VAL */
578  exc.type = OVERFLOW;
579  exc.name = "scalb";
580  exc.retval = x > zero ? HUGE_VAL : -HUGE_VAL;
581  if (_LIB_VERSION == _POSIX_)
582  errno = ERANGE;
583  else if (!matherr(&exc)) {
584  errno = ERANGE;
585  }
586  break;
587  case 33:
588  /* scalb underflow */
589  exc.type = UNDERFLOW;
590  exc.name = "scalb";
591  exc.retval = copysign(zero,x);
592  if (_LIB_VERSION == _POSIX_)
593  errno = ERANGE;
594  else if (!matherr(&exc)) {
595  errno = ERANGE;
596  }
597  break;
598  case 34:
599  /* j0(|x|>X_TLOSS) */
600  exc.type = TLOSS;
601  exc.name = "j0";
602  exc.retval = zero;
603  if (_LIB_VERSION == _POSIX_)
604  errno = ERANGE;
605  else if (!matherr(&exc)) {
606  if (_LIB_VERSION == _SVID_) {
607  (void) WRITE2(exc.name, 2);
608  (void) WRITE2(": TLOSS error\n", 14);
609  }
610  errno = ERANGE;
611  }
612  break;
613  case 35:
614  /* y0(x>X_TLOSS) */
615  exc.type = TLOSS;
616  exc.name = "y0";
617  exc.retval = zero;
618  if (_LIB_VERSION == _POSIX_)
619  errno = ERANGE;
620  else if (!matherr(&exc)) {
621  if (_LIB_VERSION == _SVID_) {
622  (void) WRITE2(exc.name, 2);
623  (void) WRITE2(": TLOSS error\n", 14);
624  }
625  errno = ERANGE;
626  }
627  break;
628  case 36:
629  /* j1(|x|>X_TLOSS) */
630  exc.type = TLOSS;
631  exc.name = "j1";
632  exc.retval = zero;
633  if (_LIB_VERSION == _POSIX_)
634  errno = ERANGE;
635  else if (!matherr(&exc)) {
636  if (_LIB_VERSION == _SVID_) {
637  (void) WRITE2(exc.name, 2);
638  (void) WRITE2(": TLOSS error\n", 14);
639  }
640  errno = ERANGE;
641  }
642  break;
643  case 37:
644  /* y1(x>X_TLOSS) */
645  exc.type = TLOSS;
646  exc.name = "y1";
647  exc.retval = zero;
648  if (_LIB_VERSION == _POSIX_)
649  errno = ERANGE;
650  else if (!matherr(&exc)) {
651  if (_LIB_VERSION == _SVID_) {
652  (void) WRITE2(exc.name, 2);
653  (void) WRITE2(": TLOSS error\n", 14);
654  }
655  errno = ERANGE;
656  }
657  break;
658  case 38:
659  /* jn(|x|>X_TLOSS) */
660  exc.type = TLOSS;
661  exc.name = "jn";
662  exc.retval = zero;
663  if (_LIB_VERSION == _POSIX_)
664  errno = ERANGE;
665  else if (!matherr(&exc)) {
666  if (_LIB_VERSION == _SVID_) {
667  (void) WRITE2(exc.name, 2);
668  (void) WRITE2(": TLOSS error\n", 14);
669  }
670  errno = ERANGE;
671  }
672  break;
673  case 39:
674  /* yn(x>X_TLOSS) */
675  exc.type = TLOSS;
676  exc.name = "yn";
677  exc.retval = zero;
678  if (_LIB_VERSION == _POSIX_)
679  errno = ERANGE;
680  else if (!matherr(&exc)) {
681  if (_LIB_VERSION == _SVID_) {
682  (void) WRITE2(exc.name, 2);
683  (void) WRITE2(": TLOSS error\n", 14);
684  }
685  errno = ERANGE;
686  }
687  break;
688  case 40:
689  /* gamma(finite) overflow */
690  exc.type = OVERFLOW;
691  exc.name = "gamma";
692  if (_LIB_VERSION == _SVID_)
693  exc.retval = HUGE;
694  else
695  exc.retval = HUGE_VAL;
696  if (_LIB_VERSION == _POSIX_)
697  errno = ERANGE;
698  else if (!matherr(&exc)) {
699  errno = ERANGE;
700  }
701  break;
702  case 41:
703  /* gamma(-integer) or gamma(0) */
704  exc.type = SING;
705  exc.name = "gamma";
706  if (_LIB_VERSION == _SVID_)
707  exc.retval = HUGE;
708  else
709  exc.retval = HUGE_VAL;
710  if (_LIB_VERSION == _POSIX_)
711  errno = EDOM;
712  else if (!matherr(&exc)) {
713  if (_LIB_VERSION == _SVID_) {
714  (void) WRITE2("gamma: SING error\n", 18);
715  }
716  errno = EDOM;
717  }
718  break;
719  case 42:
720  /* pow(NaN,0.0) */
721  /* error only if _LIB_VERSION == _SVID_ & _XOPEN_ */
722  exc.type = DOMAIN;
723  exc.name = "pow";
724  exc.retval = x;
725  if (_LIB_VERSION == _IEEE_ ||
726  _LIB_VERSION == _POSIX_) exc.retval = 1.0;
727  else if (!matherr(&exc)) {
728  errno = EDOM;
729  }
730  break;
731  }
732  return exc.retval;
733 }