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