1 | /* @(#)k_standard.c 5.1 93/09/24 */ |
2 | /* |
3 | * ==================================================== |
4 | * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. |
5 | * |
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 |
9 | * is preserved. |
10 | * ==================================================== |
11 | */ |
12 | |
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 $" ; |
15 | #endif |
16 | |
17 | #include <math.h> |
18 | #include <math_private.h> |
19 | #include <errno.h> |
20 | |
21 | #include <assert.h> |
22 | |
23 | #ifndef _USE_WRITE |
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) |
29 | #undef fflush |
30 | #endif /* !defined(_USE_WRITE) */ |
31 | |
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. */ |
35 | #if 0 |
36 | static const double zero = 0.0; /* used as const */ |
37 | #else |
38 | static double zero = 0.0; /* used as const */ |
39 | #endif |
40 | |
41 | /* |
42 | * Standard conformance (non-IEEE) on exception cases. |
43 | * Mapping: |
44 | * 1 -- acos(|x|>1) |
45 | * 2 -- asin(|x|>1) |
46 | * 3 -- atan2(+-0,+-0) |
47 | * 4 -- hypot overflow |
48 | * 5 -- cosh overflow |
49 | * 6 -- exp overflow |
50 | * 7 -- exp underflow |
51 | * 8 -- y0(0) |
52 | * 9 -- y0(-ve) |
53 | * 10-- y1(0) |
54 | * 11-- y1(-ve) |
55 | * 12-- yn(0) |
56 | * 13-- yn(-ve) |
57 | * 14-- lgamma(finite) overflow |
58 | * 15-- lgamma(-integer) |
59 | * 16-- log(0) |
60 | * 17-- log(x<0) |
61 | * 18-- log10(0) |
62 | * 19-- log10(x<0) |
63 | * 21-- pow(x,y) overflow |
64 | * 22-- pow(x,y) underflow |
65 | * 23-- pow(0,negative) |
66 | * 24-- pow(neg,non-integral) |
67 | * 25-- sinh(finite) overflow |
68 | * 26-- sqrt(negative) |
69 | * 27-- fmod(x,0) |
70 | * 28-- remainder(x,0) |
71 | * 29-- acosh(x<1) |
72 | * 30-- atanh(|x|>1) |
73 | * 31-- atanh(|x|=1) |
74 | * 32-- scalb overflow |
75 | * 33-- scalb underflow |
76 | * 34-- j0(|x|>X_TLOSS) |
77 | * 35-- y0(x>X_TLOSS) |
78 | * 36-- j1(|x|>X_TLOSS) |
79 | * 37-- y1(x>X_TLOSS) |
80 | * 38-- jn(|x|>X_TLOSS, n) |
81 | * 39-- yn(x>X_TLOSS, n) |
82 | * 40-- tgamma(finite) overflow |
83 | * 41-- tgamma(-integer) |
84 | * 43-- +0**neg |
85 | * 44-- exp2 overflow |
86 | * 45-- exp2 underflow |
87 | * 46-- exp10 overflow |
88 | * 47-- exp10 underflow |
89 | * 48-- log2(0) |
90 | * 49-- log2(x<0) |
91 | * 50-- tgamma(+-0) |
92 | */ |
93 | |
94 | |
95 | double |
96 | __kernel_standard(double x, double y, int type) |
97 | { |
98 | struct exception exc; |
99 | #ifndef HUGE_VAL /* this is the only routine that uses HUGE_VAL */ |
100 | #define HUGE_VAL inf |
101 | double inf = 0.0; |
102 | |
103 | SET_HIGH_WORD(inf,0x7ff00000); /* set inf to infinite */ |
104 | #endif |
105 | |
106 | /* The SVID struct exception uses a field "char *name;". */ |
107 | #define CSTR(func) ((char *) (type < 100 \ |
108 | ? func \ |
109 | : (type < 200 ? func "f" : func "l"))) |
110 | |
111 | #ifdef _USE_WRITE |
112 | (void) fflush(stdout); |
113 | #endif |
114 | exc.arg1 = x; |
115 | exc.arg2 = y; |
116 | switch(type) { |
117 | case 1: |
118 | case 101: |
119 | case 201: |
120 | /* acos(|x|>1) */ |
121 | exc.type = DOMAIN; |
122 | exc.name = CSTR ("acos" ); |
123 | if (_LIB_VERSION == _SVID_) |
124 | exc.retval = HUGE; |
125 | else |
126 | exc.retval = NAN; |
127 | if (_LIB_VERSION == _POSIX_) |
128 | __set_errno (EDOM); |
129 | else if (!matherr(&exc)) { |
130 | if(_LIB_VERSION == _SVID_) { |
131 | (void) WRITE2("acos: DOMAIN error\n" , 19); |
132 | } |
133 | __set_errno (EDOM); |
134 | } |
135 | break; |
136 | case 2: |
137 | case 102: |
138 | case 202: |
139 | /* asin(|x|>1) */ |
140 | exc.type = DOMAIN; |
141 | exc.name = CSTR ("asin" ); |
142 | if (_LIB_VERSION == _SVID_) |
143 | exc.retval = HUGE; |
144 | else |
145 | exc.retval = NAN; |
146 | if(_LIB_VERSION == _POSIX_) |
147 | __set_errno (EDOM); |
148 | else if (!matherr(&exc)) { |
149 | if(_LIB_VERSION == _SVID_) { |
150 | (void) WRITE2("asin: DOMAIN error\n" , 19); |
151 | } |
152 | __set_errno (EDOM); |
153 | } |
154 | break; |
155 | case 3: |
156 | case 103: |
157 | case 203: |
158 | /* atan2(+-0,+-0) */ |
159 | exc.arg1 = y; |
160 | exc.arg2 = x; |
161 | exc.type = DOMAIN; |
162 | exc.name = CSTR ("atan2" ); |
163 | assert (_LIB_VERSION == _SVID_); |
164 | exc.retval = HUGE; |
165 | if(_LIB_VERSION == _POSIX_) |
166 | __set_errno (EDOM); |
167 | else if (!matherr(&exc)) { |
168 | if(_LIB_VERSION == _SVID_) { |
169 | (void) WRITE2("atan2: DOMAIN error\n" , 20); |
170 | } |
171 | __set_errno (EDOM); |
172 | } |
173 | break; |
174 | case 4: |
175 | case 104: |
176 | case 204: |
177 | /* hypot(finite,finite) overflow */ |
178 | exc.type = OVERFLOW; |
179 | exc.name = CSTR ("hypot" ); |
180 | if (_LIB_VERSION == _SVID_) |
181 | exc.retval = HUGE; |
182 | else |
183 | exc.retval = HUGE_VAL; |
184 | if (_LIB_VERSION == _POSIX_) |
185 | __set_errno (ERANGE); |
186 | else if (!matherr(&exc)) { |
187 | __set_errno (ERANGE); |
188 | } |
189 | break; |
190 | case 5: |
191 | case 105: |
192 | case 205: |
193 | /* cosh(finite) overflow */ |
194 | exc.type = OVERFLOW; |
195 | exc.name = CSTR ("cosh" ); |
196 | if (_LIB_VERSION == _SVID_) |
197 | exc.retval = HUGE; |
198 | else |
199 | exc.retval = HUGE_VAL; |
200 | if (_LIB_VERSION == _POSIX_) |
201 | __set_errno (ERANGE); |
202 | else if (!matherr(&exc)) { |
203 | __set_errno (ERANGE); |
204 | } |
205 | break; |
206 | case 6: |
207 | case 106: |
208 | case 206: |
209 | /* exp(finite) overflow */ |
210 | exc.type = OVERFLOW; |
211 | exc.name = CSTR ("exp" ); |
212 | if (_LIB_VERSION == _SVID_) |
213 | exc.retval = HUGE; |
214 | else |
215 | exc.retval = HUGE_VAL; |
216 | if (_LIB_VERSION == _POSIX_) |
217 | __set_errno (ERANGE); |
218 | else if (!matherr(&exc)) { |
219 | __set_errno (ERANGE); |
220 | } |
221 | break; |
222 | case 7: |
223 | case 107: |
224 | case 207: |
225 | /* exp(finite) underflow */ |
226 | exc.type = UNDERFLOW; |
227 | exc.name = CSTR ("exp" ); |
228 | exc.retval = zero; |
229 | if (_LIB_VERSION == _POSIX_) |
230 | __set_errno (ERANGE); |
231 | else if (!matherr(&exc)) { |
232 | __set_errno (ERANGE); |
233 | } |
234 | break; |
235 | case 8: |
236 | case 108: |
237 | case 208: |
238 | /* y0(0) = -inf */ |
239 | exc.type = DOMAIN; /* should be SING for IEEE */ |
240 | exc.name = CSTR ("y0" ); |
241 | if (_LIB_VERSION == _SVID_) |
242 | exc.retval = -HUGE; |
243 | else |
244 | exc.retval = -HUGE_VAL; |
245 | if (_LIB_VERSION == _POSIX_) |
246 | __set_errno (ERANGE); |
247 | else if (!matherr(&exc)) { |
248 | if (_LIB_VERSION == _SVID_) { |
249 | (void) WRITE2("y0: DOMAIN error\n" , 17); |
250 | } |
251 | __set_errno (EDOM); |
252 | } |
253 | break; |
254 | case 9: |
255 | case 109: |
256 | case 209: |
257 | /* y0(x<0) = NaN */ |
258 | exc.type = DOMAIN; |
259 | exc.name = CSTR ("y0" ); |
260 | if (_LIB_VERSION == _SVID_) |
261 | exc.retval = -HUGE; |
262 | else |
263 | exc.retval = NAN; |
264 | if (_LIB_VERSION == _POSIX_) |
265 | __set_errno (EDOM); |
266 | else if (!matherr(&exc)) { |
267 | if (_LIB_VERSION == _SVID_) { |
268 | (void) WRITE2("y0: DOMAIN error\n" , 17); |
269 | } |
270 | __set_errno (EDOM); |
271 | } |
272 | break; |
273 | case 10: |
274 | case 110: |
275 | case 210: |
276 | /* y1(0) = -inf */ |
277 | exc.type = DOMAIN; /* should be SING for IEEE */ |
278 | exc.name = CSTR ("y1" ); |
279 | if (_LIB_VERSION == _SVID_) |
280 | exc.retval = -HUGE; |
281 | else |
282 | exc.retval = -HUGE_VAL; |
283 | if (_LIB_VERSION == _POSIX_) |
284 | __set_errno (ERANGE); |
285 | else if (!matherr(&exc)) { |
286 | if (_LIB_VERSION == _SVID_) { |
287 | (void) WRITE2("y1: DOMAIN error\n" , 17); |
288 | } |
289 | __set_errno (EDOM); |
290 | } |
291 | break; |
292 | case 11: |
293 | case 111: |
294 | case 211: |
295 | /* y1(x<0) = NaN */ |
296 | exc.type = DOMAIN; |
297 | exc.name = CSTR ("y1" ); |
298 | if (_LIB_VERSION == _SVID_) |
299 | exc.retval = -HUGE; |
300 | else |
301 | exc.retval = NAN; |
302 | if (_LIB_VERSION == _POSIX_) |
303 | __set_errno (EDOM); |
304 | else if (!matherr(&exc)) { |
305 | if (_LIB_VERSION == _SVID_) { |
306 | (void) WRITE2("y1: DOMAIN error\n" , 17); |
307 | } |
308 | __set_errno (EDOM); |
309 | } |
310 | break; |
311 | case 12: |
312 | case 112: |
313 | case 212: |
314 | /* yn(n,0) = -inf */ |
315 | exc.type = DOMAIN; /* should be SING for IEEE */ |
316 | exc.name = CSTR ("yn" ); |
317 | if (_LIB_VERSION == _SVID_) |
318 | exc.retval = -HUGE; |
319 | else |
320 | exc.retval = ((x < 0 && ((int) x & 1) != 0) |
321 | ? HUGE_VAL |
322 | : -HUGE_VAL); |
323 | if (_LIB_VERSION == _POSIX_) |
324 | __set_errno (ERANGE); |
325 | else if (!matherr(&exc)) { |
326 | if (_LIB_VERSION == _SVID_) { |
327 | (void) WRITE2("yn: DOMAIN error\n" , 17); |
328 | } |
329 | __set_errno (EDOM); |
330 | } |
331 | break; |
332 | case 13: |
333 | case 113: |
334 | case 213: |
335 | /* yn(x<0) = NaN */ |
336 | exc.type = DOMAIN; |
337 | exc.name = CSTR ("yn" ); |
338 | if (_LIB_VERSION == _SVID_) |
339 | exc.retval = -HUGE; |
340 | else |
341 | exc.retval = NAN; |
342 | if (_LIB_VERSION == _POSIX_) |
343 | __set_errno (EDOM); |
344 | else if (!matherr(&exc)) { |
345 | if (_LIB_VERSION == _SVID_) { |
346 | (void) WRITE2("yn: DOMAIN error\n" , 17); |
347 | } |
348 | __set_errno (EDOM); |
349 | } |
350 | break; |
351 | case 14: |
352 | case 114: |
353 | case 214: |
354 | /* lgamma(finite) overflow */ |
355 | exc.type = OVERFLOW; |
356 | exc.name = CSTR ("lgamma" ); |
357 | if (_LIB_VERSION == _SVID_) |
358 | exc.retval = HUGE; |
359 | else |
360 | exc.retval = HUGE_VAL; |
361 | if (_LIB_VERSION == _POSIX_) |
362 | __set_errno (ERANGE); |
363 | else if (!matherr(&exc)) { |
364 | __set_errno (ERANGE); |
365 | } |
366 | break; |
367 | case 15: |
368 | case 115: |
369 | case 215: |
370 | /* lgamma(-integer) or lgamma(0) */ |
371 | exc.type = SING; |
372 | exc.name = CSTR ("lgamma" ); |
373 | if (_LIB_VERSION == _SVID_) |
374 | exc.retval = HUGE; |
375 | else |
376 | exc.retval = HUGE_VAL; |
377 | if (_LIB_VERSION == _POSIX_) |
378 | __set_errno (ERANGE); |
379 | else if (!matherr(&exc)) { |
380 | if (_LIB_VERSION == _SVID_) { |
381 | (void) WRITE2("lgamma: SING error\n" , 19); |
382 | } |
383 | __set_errno (EDOM); |
384 | } |
385 | break; |
386 | case 16: |
387 | case 116: |
388 | case 216: |
389 | /* log(0) */ |
390 | exc.type = SING; |
391 | exc.name = CSTR ("log" ); |
392 | if (_LIB_VERSION == _SVID_) |
393 | exc.retval = -HUGE; |
394 | else |
395 | exc.retval = -HUGE_VAL; |
396 | if (_LIB_VERSION == _POSIX_) |
397 | __set_errno (ERANGE); |
398 | else if (!matherr(&exc)) { |
399 | if (_LIB_VERSION == _SVID_) { |
400 | (void) WRITE2("log: SING error\n" , 16); |
401 | } |
402 | __set_errno (EDOM); |
403 | } |
404 | break; |
405 | case 17: |
406 | case 117: |
407 | case 217: |
408 | /* log(x<0) */ |
409 | exc.type = DOMAIN; |
410 | exc.name = CSTR ("log" ); |
411 | if (_LIB_VERSION == _SVID_) |
412 | exc.retval = -HUGE; |
413 | else |
414 | exc.retval = NAN; |
415 | if (_LIB_VERSION == _POSIX_) |
416 | __set_errno (EDOM); |
417 | else if (!matherr(&exc)) { |
418 | if (_LIB_VERSION == _SVID_) { |
419 | (void) WRITE2("log: DOMAIN error\n" , 18); |
420 | } |
421 | __set_errno (EDOM); |
422 | } |
423 | break; |
424 | case 18: |
425 | case 118: |
426 | case 218: |
427 | /* log10(0) */ |
428 | exc.type = SING; |
429 | exc.name = CSTR ("log10" ); |
430 | if (_LIB_VERSION == _SVID_) |
431 | exc.retval = -HUGE; |
432 | else |
433 | exc.retval = -HUGE_VAL; |
434 | if (_LIB_VERSION == _POSIX_) |
435 | __set_errno (ERANGE); |
436 | else if (!matherr(&exc)) { |
437 | if (_LIB_VERSION == _SVID_) { |
438 | (void) WRITE2("log10: SING error\n" , 18); |
439 | } |
440 | __set_errno (EDOM); |
441 | } |
442 | break; |
443 | case 19: |
444 | case 119: |
445 | case 219: |
446 | /* log10(x<0) */ |
447 | exc.type = DOMAIN; |
448 | exc.name = CSTR ("log10" ); |
449 | if (_LIB_VERSION == _SVID_) |
450 | exc.retval = -HUGE; |
451 | else |
452 | exc.retval = NAN; |
453 | if (_LIB_VERSION == _POSIX_) |
454 | __set_errno (EDOM); |
455 | else if (!matherr(&exc)) { |
456 | if (_LIB_VERSION == _SVID_) { |
457 | (void) WRITE2("log10: DOMAIN error\n" , 20); |
458 | } |
459 | __set_errno (EDOM); |
460 | } |
461 | break; |
462 | case 21: |
463 | case 121: |
464 | case 221: |
465 | /* pow(x,y) overflow */ |
466 | exc.type = OVERFLOW; |
467 | exc.name = CSTR ("pow" ); |
468 | if (_LIB_VERSION == _SVID_) { |
469 | exc.retval = HUGE; |
470 | y *= 0.5; |
471 | if(x<zero&&__rint(y)!=y) exc.retval = -HUGE; |
472 | } else { |
473 | exc.retval = HUGE_VAL; |
474 | y *= 0.5; |
475 | if(x<zero&&__rint(y)!=y) exc.retval = -HUGE_VAL; |
476 | } |
477 | if (_LIB_VERSION == _POSIX_) |
478 | __set_errno (ERANGE); |
479 | else if (!matherr(&exc)) { |
480 | __set_errno (ERANGE); |
481 | } |
482 | break; |
483 | case 22: |
484 | case 122: |
485 | case 222: |
486 | /* pow(x,y) underflow */ |
487 | exc.type = UNDERFLOW; |
488 | exc.name = CSTR ("pow" ); |
489 | exc.retval = zero; |
490 | y *= 0.5; |
491 | if (x < zero && __rint (y) != y) |
492 | exc.retval = -zero; |
493 | if (_LIB_VERSION == _POSIX_) |
494 | __set_errno (ERANGE); |
495 | else if (!matherr(&exc)) { |
496 | __set_errno (ERANGE); |
497 | } |
498 | break; |
499 | case 23: |
500 | case 123: |
501 | case 223: |
502 | /* -0**neg */ |
503 | exc.type = DOMAIN; |
504 | exc.name = CSTR ("pow" ); |
505 | if (_LIB_VERSION == _SVID_) |
506 | exc.retval = zero; |
507 | else |
508 | exc.retval = -HUGE_VAL; |
509 | if (_LIB_VERSION == _POSIX_) |
510 | __set_errno (ERANGE); |
511 | else if (!matherr(&exc)) { |
512 | if (_LIB_VERSION == _SVID_) { |
513 | (void) WRITE2("pow(0,neg): DOMAIN error\n" , 25); |
514 | } |
515 | __set_errno (EDOM); |
516 | } |
517 | break; |
518 | case 43: |
519 | case 143: |
520 | case 243: |
521 | /* +0**neg */ |
522 | exc.type = DOMAIN; |
523 | exc.name = CSTR ("pow" ); |
524 | if (_LIB_VERSION == _SVID_) |
525 | exc.retval = zero; |
526 | else |
527 | exc.retval = HUGE_VAL; |
528 | if (_LIB_VERSION == _POSIX_) |
529 | __set_errno (ERANGE); |
530 | else if (!matherr(&exc)) { |
531 | if (_LIB_VERSION == _SVID_) { |
532 | (void) WRITE2("pow(0,neg): DOMAIN error\n" , 25); |
533 | } |
534 | __set_errno (EDOM); |
535 | } |
536 | break; |
537 | case 24: |
538 | case 124: |
539 | case 224: |
540 | /* neg**non-integral */ |
541 | exc.type = DOMAIN; |
542 | exc.name = CSTR ("pow" ); |
543 | if (_LIB_VERSION == _SVID_) |
544 | exc.retval = zero; |
545 | else |
546 | exc.retval = zero/zero; /* X/Open allow NaN */ |
547 | if (_LIB_VERSION == _POSIX_) |
548 | __set_errno (EDOM); |
549 | else if (!matherr(&exc)) { |
550 | if (_LIB_VERSION == _SVID_) { |
551 | (void) WRITE2("neg**non-integral: DOMAIN error\n" , 32); |
552 | } |
553 | __set_errno (EDOM); |
554 | } |
555 | break; |
556 | case 25: |
557 | case 125: |
558 | case 225: |
559 | /* sinh(finite) overflow */ |
560 | exc.type = OVERFLOW; |
561 | exc.name = CSTR ("sinh" ); |
562 | if (_LIB_VERSION == _SVID_) |
563 | exc.retval = ( (x>zero) ? HUGE : -HUGE); |
564 | else |
565 | exc.retval = ( (x>zero) ? HUGE_VAL : -HUGE_VAL); |
566 | if (_LIB_VERSION == _POSIX_) |
567 | __set_errno (ERANGE); |
568 | else if (!matherr(&exc)) { |
569 | __set_errno (ERANGE); |
570 | } |
571 | break; |
572 | case 26: |
573 | case 126: |
574 | case 226: |
575 | /* sqrt(x<0) */ |
576 | exc.type = DOMAIN; |
577 | exc.name = CSTR ("sqrt" ); |
578 | if (_LIB_VERSION == _SVID_) |
579 | exc.retval = zero; |
580 | else |
581 | exc.retval = zero/zero; |
582 | if (_LIB_VERSION == _POSIX_) |
583 | __set_errno (EDOM); |
584 | else if (!matherr(&exc)) { |
585 | if (_LIB_VERSION == _SVID_) { |
586 | (void) WRITE2("sqrt: DOMAIN error\n" , 19); |
587 | } |
588 | __set_errno (EDOM); |
589 | } |
590 | break; |
591 | case 27: |
592 | case 127: |
593 | case 227: |
594 | /* fmod(x,0) */ |
595 | exc.type = DOMAIN; |
596 | exc.name = CSTR ("fmod" ); |
597 | if (_LIB_VERSION == _SVID_) |
598 | exc.retval = x; |
599 | else |
600 | exc.retval = zero/zero; |
601 | if (_LIB_VERSION == _POSIX_) |
602 | __set_errno (EDOM); |
603 | else if (!matherr(&exc)) { |
604 | if (_LIB_VERSION == _SVID_) { |
605 | (void) WRITE2("fmod: DOMAIN error\n" , 20); |
606 | } |
607 | __set_errno (EDOM); |
608 | } |
609 | break; |
610 | case 28: |
611 | case 128: |
612 | case 228: |
613 | /* remainder(x,0) */ |
614 | exc.type = DOMAIN; |
615 | exc.name = CSTR ("remainder" ); |
616 | exc.retval = zero/zero; |
617 | if (_LIB_VERSION == _POSIX_) |
618 | __set_errno (EDOM); |
619 | else if (!matherr(&exc)) { |
620 | if (_LIB_VERSION == _SVID_) { |
621 | (void) WRITE2("remainder: DOMAIN error\n" , 24); |
622 | } |
623 | __set_errno (EDOM); |
624 | } |
625 | break; |
626 | case 29: |
627 | case 129: |
628 | case 229: |
629 | /* acosh(x<1) */ |
630 | exc.type = DOMAIN; |
631 | exc.name = CSTR ("acosh" ); |
632 | exc.retval = zero/zero; |
633 | if (_LIB_VERSION == _POSIX_) |
634 | __set_errno (EDOM); |
635 | else if (!matherr(&exc)) { |
636 | if (_LIB_VERSION == _SVID_) { |
637 | (void) WRITE2("acosh: DOMAIN error\n" , 20); |
638 | } |
639 | __set_errno (EDOM); |
640 | } |
641 | break; |
642 | case 30: |
643 | case 130: |
644 | case 230: |
645 | /* atanh(|x|>1) */ |
646 | exc.type = DOMAIN; |
647 | exc.name = CSTR ("atanh" ); |
648 | exc.retval = zero/zero; |
649 | if (_LIB_VERSION == _POSIX_) |
650 | __set_errno (EDOM); |
651 | else if (!matherr(&exc)) { |
652 | if (_LIB_VERSION == _SVID_) { |
653 | (void) WRITE2("atanh: DOMAIN error\n" , 20); |
654 | } |
655 | __set_errno (EDOM); |
656 | } |
657 | break; |
658 | case 31: |
659 | case 131: |
660 | case 231: |
661 | /* atanh(|x|=1) */ |
662 | exc.type = SING; |
663 | exc.name = CSTR ("atanh" ); |
664 | exc.retval = x/zero; /* sign(x)*inf */ |
665 | if (_LIB_VERSION == _POSIX_) |
666 | __set_errno (ERANGE); |
667 | else if (!matherr(&exc)) { |
668 | if (_LIB_VERSION == _SVID_) { |
669 | (void) WRITE2("atanh: SING error\n" , 18); |
670 | } |
671 | __set_errno (EDOM); |
672 | } |
673 | break; |
674 | case 32: |
675 | case 132: |
676 | case 232: |
677 | /* scalb overflow; SVID also returns +-HUGE_VAL */ |
678 | exc.type = OVERFLOW; |
679 | exc.name = CSTR ("scalb" ); |
680 | exc.retval = x > zero ? HUGE_VAL : -HUGE_VAL; |
681 | if (_LIB_VERSION == _POSIX_) |
682 | __set_errno (ERANGE); |
683 | else if (!matherr(&exc)) { |
684 | __set_errno (ERANGE); |
685 | } |
686 | break; |
687 | case 33: |
688 | case 133: |
689 | case 233: |
690 | /* scalb underflow */ |
691 | exc.type = UNDERFLOW; |
692 | exc.name = CSTR ("scalb" ); |
693 | exc.retval = __copysign(zero,x); |
694 | if (_LIB_VERSION == _POSIX_) |
695 | __set_errno (ERANGE); |
696 | else if (!matherr(&exc)) { |
697 | __set_errno (ERANGE); |
698 | } |
699 | break; |
700 | case 34: |
701 | case 134: |
702 | case 234: |
703 | /* j0(|x|>X_TLOSS) */ |
704 | exc.type = TLOSS; |
705 | exc.name = CSTR ("j0" ); |
706 | exc.retval = zero; |
707 | if (_LIB_VERSION == _POSIX_) |
708 | __set_errno (ERANGE); |
709 | else if (!matherr(&exc)) { |
710 | if (_LIB_VERSION == _SVID_) { |
711 | (void) WRITE2(exc.name, 2); |
712 | (void) WRITE2(": TLOSS error\n" , 14); |
713 | } |
714 | __set_errno (ERANGE); |
715 | } |
716 | break; |
717 | case 35: |
718 | case 135: |
719 | case 235: |
720 | /* y0(x>X_TLOSS) */ |
721 | exc.type = TLOSS; |
722 | exc.name = CSTR ("y0" ); |
723 | exc.retval = zero; |
724 | if (_LIB_VERSION == _POSIX_) |
725 | __set_errno (ERANGE); |
726 | else if (!matherr(&exc)) { |
727 | if (_LIB_VERSION == _SVID_) { |
728 | (void) WRITE2(exc.name, 2); |
729 | (void) WRITE2(": TLOSS error\n" , 14); |
730 | } |
731 | __set_errno (ERANGE); |
732 | } |
733 | break; |
734 | case 36: |
735 | case 136: |
736 | case 236: |
737 | /* j1(|x|>X_TLOSS) */ |
738 | exc.type = TLOSS; |
739 | exc.name = CSTR ("j1" ); |
740 | exc.retval = zero; |
741 | if (_LIB_VERSION == _POSIX_) |
742 | __set_errno (ERANGE); |
743 | else if (!matherr(&exc)) { |
744 | if (_LIB_VERSION == _SVID_) { |
745 | (void) WRITE2(exc.name, 2); |
746 | (void) WRITE2(": TLOSS error\n" , 14); |
747 | } |
748 | __set_errno (ERANGE); |
749 | } |
750 | break; |
751 | case 37: |
752 | case 137: |
753 | case 237: |
754 | /* y1(x>X_TLOSS) */ |
755 | exc.type = TLOSS; |
756 | exc.name = CSTR ("y1" ); |
757 | exc.retval = zero; |
758 | if (_LIB_VERSION == _POSIX_) |
759 | __set_errno (ERANGE); |
760 | else if (!matherr(&exc)) { |
761 | if (_LIB_VERSION == _SVID_) { |
762 | (void) WRITE2(exc.name, 2); |
763 | (void) WRITE2(": TLOSS error\n" , 14); |
764 | } |
765 | __set_errno (ERANGE); |
766 | } |
767 | break; |
768 | case 38: |
769 | case 138: |
770 | case 238: |
771 | /* jn(|x|>X_TLOSS) */ |
772 | exc.type = TLOSS; |
773 | exc.name = CSTR ("jn" ); |
774 | exc.retval = zero; |
775 | if (_LIB_VERSION == _POSIX_) |
776 | __set_errno (ERANGE); |
777 | else if (!matherr(&exc)) { |
778 | if (_LIB_VERSION == _SVID_) { |
779 | (void) WRITE2(exc.name, 2); |
780 | (void) WRITE2(": TLOSS error\n" , 14); |
781 | } |
782 | __set_errno (ERANGE); |
783 | } |
784 | break; |
785 | case 39: |
786 | case 139: |
787 | case 239: |
788 | /* yn(x>X_TLOSS) */ |
789 | exc.type = TLOSS; |
790 | exc.name = CSTR ("yn" ); |
791 | exc.retval = zero; |
792 | if (_LIB_VERSION == _POSIX_) |
793 | __set_errno (ERANGE); |
794 | else if (!matherr(&exc)) { |
795 | if (_LIB_VERSION == _SVID_) { |
796 | (void) WRITE2(exc.name, 2); |
797 | (void) WRITE2(": TLOSS error\n" , 14); |
798 | } |
799 | __set_errno (ERANGE); |
800 | } |
801 | break; |
802 | case 40: |
803 | case 140: |
804 | case 240: |
805 | /* tgamma(finite) overflow */ |
806 | exc.type = OVERFLOW; |
807 | exc.name = CSTR ("tgamma" ); |
808 | exc.retval = __copysign (HUGE_VAL, x); |
809 | if (_LIB_VERSION == _POSIX_) |
810 | __set_errno (ERANGE); |
811 | else if (!matherr(&exc)) { |
812 | __set_errno (ERANGE); |
813 | } |
814 | break; |
815 | case 41: |
816 | case 141: |
817 | case 241: |
818 | /* tgamma(-integer) */ |
819 | exc.type = SING; |
820 | exc.name = CSTR ("tgamma" ); |
821 | exc.retval = NAN; |
822 | if (_LIB_VERSION == _POSIX_) |
823 | __set_errno (EDOM); |
824 | else if (!matherr(&exc)) { |
825 | if (_LIB_VERSION == _SVID_) { |
826 | (void) WRITE2("tgamma: SING error\n" , 18); |
827 | exc.retval = HUGE_VAL; |
828 | } |
829 | __set_errno (EDOM); |
830 | } |
831 | break; |
832 | |
833 | case 44: |
834 | case 144: |
835 | case 244: |
836 | /* exp(finite) overflow */ |
837 | exc.type = OVERFLOW; |
838 | exc.name = CSTR ("exp2" ); |
839 | if (_LIB_VERSION == _SVID_) |
840 | exc.retval = HUGE; |
841 | else |
842 | exc.retval = HUGE_VAL; |
843 | if (_LIB_VERSION == _POSIX_) |
844 | __set_errno (ERANGE); |
845 | else if (!matherr(&exc)) { |
846 | __set_errno (ERANGE); |
847 | } |
848 | break; |
849 | case 45: |
850 | case 145: |
851 | case 245: |
852 | /* exp(finite) underflow */ |
853 | exc.type = UNDERFLOW; |
854 | exc.name = CSTR ("exp2" ); |
855 | exc.retval = zero; |
856 | if (_LIB_VERSION == _POSIX_) |
857 | __set_errno (ERANGE); |
858 | else if (!matherr(&exc)) { |
859 | __set_errno (ERANGE); |
860 | } |
861 | break; |
862 | |
863 | case 46: |
864 | case 146: |
865 | case 246: |
866 | /* exp(finite) overflow */ |
867 | exc.type = OVERFLOW; |
868 | exc.name = CSTR ("exp10" ); |
869 | if (_LIB_VERSION == _SVID_) |
870 | exc.retval = HUGE; |
871 | else |
872 | exc.retval = HUGE_VAL; |
873 | if (_LIB_VERSION == _POSIX_) |
874 | __set_errno (ERANGE); |
875 | else if (!matherr(&exc)) { |
876 | __set_errno (ERANGE); |
877 | } |
878 | break; |
879 | case 47: |
880 | case 147: |
881 | case 247: |
882 | /* exp(finite) underflow */ |
883 | exc.type = UNDERFLOW; |
884 | exc.name = CSTR ("exp10" ); |
885 | exc.retval = zero; |
886 | if (_LIB_VERSION == _POSIX_) |
887 | __set_errno (ERANGE); |
888 | else if (!matherr(&exc)) { |
889 | __set_errno (ERANGE); |
890 | } |
891 | break; |
892 | case 48: |
893 | case 148: |
894 | case 248: |
895 | /* log2(0) */ |
896 | exc.type = SING; |
897 | exc.name = CSTR ("log2" ); |
898 | if (_LIB_VERSION == _SVID_) |
899 | exc.retval = -HUGE; |
900 | else |
901 | exc.retval = -HUGE_VAL; |
902 | if (_LIB_VERSION == _POSIX_) |
903 | __set_errno (ERANGE); |
904 | else if (!matherr(&exc)) { |
905 | __set_errno (EDOM); |
906 | } |
907 | break; |
908 | case 49: |
909 | case 149: |
910 | case 249: |
911 | /* log2(x<0) */ |
912 | exc.type = DOMAIN; |
913 | exc.name = CSTR ("log2" ); |
914 | if (_LIB_VERSION == _SVID_) |
915 | exc.retval = -HUGE; |
916 | else |
917 | exc.retval = NAN; |
918 | if (_LIB_VERSION == _POSIX_) |
919 | __set_errno (EDOM); |
920 | else if (!matherr(&exc)) { |
921 | __set_errno (EDOM); |
922 | } |
923 | break; |
924 | case 50: |
925 | case 150: |
926 | case 250: |
927 | /* tgamma(+-0) */ |
928 | exc.type = SING; |
929 | exc.name = CSTR ("tgamma" ); |
930 | exc.retval = __copysign (HUGE_VAL, x); |
931 | if (_LIB_VERSION == _POSIX_) |
932 | __set_errno (ERANGE); |
933 | else if (!matherr(&exc)) { |
934 | if (_LIB_VERSION == _SVID_) |
935 | (void) WRITE2("tgamma: SING error\n" , 18); |
936 | __set_errno (ERANGE); |
937 | } |
938 | break; |
939 | |
940 | /* #### Last used is 50/150/250 ### */ |
941 | } |
942 | return exc.retval; |
943 | } |
944 | |