]>
Commit | Line | Data |
---|---|---|
f56f9124 | 1 | /* Implement __kernel_standard_l. |
b168057a | 2 | Copyright (C) 2012-2015 Free Software Foundation, Inc. |
f56f9124 JM |
3 | This file is part of the GNU C Library. |
4 | ||
5 | The GNU C Library is free software; you can redistribute it and/or | |
6 | modify it under the terms of the GNU Lesser General Public | |
7 | License as published by the Free Software Foundation; either | |
8 | version 2.1 of the License, or (at your option) any later version. | |
9 | ||
10 | The GNU C Library is distributed in the hope that it will be useful, | |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 | Lesser General Public License for more details. | |
14 | ||
15 | You should have received a copy of the GNU Lesser General Public | |
16 | License along with the GNU C Library; if not, see | |
17 | <http://www.gnu.org/licenses/>. | |
18 | ||
19 | Parts based on k_standard.c from fdlibm: */ | |
20 | ||
21 | /* @(#)k_standard.c 5.1 93/09/24 */ | |
22 | /* | |
23 | * ==================================================== | |
24 | * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. | |
25 | * | |
26 | * Developed at SunPro, a Sun Microsystems, Inc. business. | |
27 | * Permission to use, copy, modify, and distribute this | |
28 | * software is freely granted, provided that this notice | |
29 | * is preserved. | |
30 | * ==================================================== | |
31 | */ | |
32 | ||
33 | #include <math.h> | |
34 | #include <math_private.h> | |
35 | #include <float.h> | |
36 | #include <errno.h> | |
37 | ||
38 | ||
39 | static double zero = 0.0; | |
40 | ||
41 | /* Handle errors for a libm function as specified by TYPE (see | |
42 | comments in k_standard.c for details), with arguments X and Y, | |
43 | returning the appropriate return value for that function. */ | |
44 | ||
45 | long double | |
46 | __kernel_standard_l (long double x, long double y, int type) | |
47 | { | |
48 | double dx, dy; | |
49 | struct exception exc; | |
50 | ||
51 | if (isfinite (x)) | |
52 | { | |
53 | long double ax = fabsl (x); | |
54 | if (ax > DBL_MAX) | |
55 | dx = __copysignl (DBL_MAX, x); | |
56 | else if (ax > 0 && ax < DBL_MIN) | |
57 | dx = __copysignl (DBL_MIN, x); | |
58 | else | |
59 | dx = x; | |
60 | } | |
61 | else | |
62 | dx = x; | |
63 | if (isfinite (y)) | |
64 | { | |
65 | long double ay = fabsl (y); | |
66 | if (ay > DBL_MAX) | |
67 | dy = __copysignl (DBL_MAX, y); | |
68 | else if (ay > 0 && ay < DBL_MIN) | |
69 | dy = __copysignl (DBL_MIN, y); | |
70 | else | |
71 | dy = y; | |
72 | } | |
73 | else | |
74 | dy = y; | |
75 | ||
76 | switch (type) | |
77 | { | |
78 | case 221: | |
79 | /* powl (x, y) overflow. */ | |
80 | exc.arg1 = dx; | |
81 | exc.arg2 = dy; | |
82 | exc.type = OVERFLOW; | |
83 | exc.name = (char *) "powl"; | |
84 | if (_LIB_VERSION == _SVID_) | |
85 | { | |
86 | exc.retval = HUGE; | |
87 | y *= 0.5; | |
88 | if (x < zero && __rintl (y) != y) | |
89 | exc.retval = -HUGE; | |
90 | } | |
91 | else | |
92 | { | |
93 | exc.retval = HUGE_VAL; | |
94 | y *= 0.5; | |
95 | if (x < zero && __rintl (y) != y) | |
96 | exc.retval = -HUGE_VAL; | |
97 | } | |
98 | if (_LIB_VERSION == _POSIX_) | |
99 | __set_errno (ERANGE); | |
100 | else if (!matherr (&exc)) | |
101 | __set_errno (ERANGE); | |
102 | return exc.retval; | |
103 | ||
104 | case 222: | |
105 | /* powl (x, y) underflow. */ | |
106 | exc.arg1 = dx; | |
107 | exc.arg2 = dy; | |
108 | exc.type = UNDERFLOW; | |
109 | exc.name = (char *) "powl"; | |
110 | exc.retval = zero; | |
111 | y *= 0.5; | |
112 | if (x < zero && __rintl (y) != y) | |
113 | exc.retval = -zero; | |
114 | if (_LIB_VERSION == _POSIX_) | |
115 | __set_errno (ERANGE); | |
116 | else if (!matherr (&exc)) | |
117 | __set_errno (ERANGE); | |
118 | return exc.retval; | |
119 | ||
120 | default: | |
121 | return __kernel_standard (dx, dy, type); | |
122 | } | |
123 | } |