|
0
|
1 //=========================================================================== |
|
|
2 // |
|
|
3 // signgam.cxx |
|
|
4 // |
|
|
5 // Support sign of the gamma*() functions in Math library |
|
|
6 // |
|
|
7 //=========================================================================== |
|
|
8 //####COPYRIGHTBEGIN#### |
|
|
9 // |
|
|
10 // ------------------------------------------- |
|
|
11 // The contents of this file are subject to the Cygnus eCos Public License |
|
|
12 // Version 1.0 (the "License"); you may not use this file except in |
|
|
13 // compliance with the License. You may obtain a copy of the License at |
|
|
14 // http://sourceware.cygnus.com/ecos |
|
|
15 // |
|
|
16 // Software distributed under the License is distributed on an "AS IS" |
|
|
17 // basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the |
|
|
18 // License for the specific language governing rights and limitations under |
|
|
19 // the License. |
|
|
20 // |
|
|
21 // The Original Code is eCos - Embedded Cygnus Operating System, released |
|
|
22 // September 30, 1998. |
|
|
23 // |
|
|
24 // The Initial Developer of the Original Code is Cygnus. Portions created |
|
|
25 // by Cygnus are Copyright (C) 1998 Cygnus Solutions. All Rights Reserved. |
|
|
26 // ------------------------------------------- |
|
|
27 // |
|
|
28 //####COPYRIGHTEND#### |
|
|
29 //=========================================================================== |
|
|
30 //#####DESCRIPTIONBEGIN#### |
|
|
31 // |
|
|
32 // Author(s): jlarmour@cygnus.co.uk |
|
|
33 // Contributors: jlarmour@cygnus.co.uk |
|
|
34 // Date: 1998-02-13 |
|
|
35 // Purpose: |
|
|
36 // Description: Contains the accessor functions to get and set the stored sign |
|
|
37 // of the gamma*() functions in the math library |
|
|
38 // Usage: |
|
|
39 // |
|
|
40 //####DESCRIPTIONEND#### |
|
|
41 // |
|
|
42 //=========================================================================== |
|
|
43 |
|
|
44 /* @(#)k_standard.c 1.3 95/01/18 */ |
|
|
45 /* |
|
|
46 * ==================================================== |
|
|
47 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. |
|
|
48 * |
|
|
49 * Developed at SunSoft, a Sun Microsystems, Inc. business. |
|
|
50 * Permission to use, copy, modify, and distribute this |
|
|
51 * software is freely granted, provided that this notice |
|
|
52 * is preserved. |
|
|
53 * ==================================================== |
|
|
54 * |
|
|
55 */ |
|
|
56 |
|
|
57 // CONFIGURATION |
|
|
58 |
|
|
59 #include <pkgconf/libm.h> // Configuration header |
|
|
60 |
|
|
61 // Include the Math library? |
|
|
62 #ifdef CYGPKG_LIBM |
|
|
63 |
|
|
64 // INCLUDES |
|
|
65 |
|
|
66 #include <cyg/infra/cyg_type.h> // Common type definitions and support |
|
|
67 #include <cyg/infra/cyg_trac.h> // Tracing macros |
|
|
68 |
|
|
69 #include <math.h> // Main header for math library |
|
|
70 #include "mathincl/fdlibm.h" // Internal header for math library |
|
|
71 |
|
|
72 #include <cyg/error/codes.h> // standard error codes |
|
|
73 |
|
|
74 #ifndef CYGSEM_LIBM_COMPAT_IEEE_ONLY |
|
|
75 #include <errno.h> |
|
|
76 #else |
|
|
77 static int errno; // this whole file won't be used if we're IEEE only, but |
|
|
78 // doing this keeps the compiler happy |
|
|
79 #endif |
|
|
80 |
|
|
81 #ifdef CYGSEM_LIBM_USE_STDERR |
|
|
82 |
|
|
83 #include <stdio.h> |
|
|
84 #define WRITE2(u,v) fputs(u, stderr) |
|
|
85 |
|
|
86 #else |
|
|
87 |
|
|
88 #define WRITE2(u,v) 0 |
|
|
89 |
|
|
90 #endif // ifdef CYGSEM_LIBM_USE_STDERR |
|
|
91 |
|
|
92 |
|
|
93 // GLOBALS |
|
|
94 |
|
|
95 static const double zero = 0.0; |
|
|
96 |
|
|
97 // FUNCTIONS |
|
|
98 |
|
|
99 /* |
|
|
100 * Standard conformance (non-IEEE) on exception cases. |
|
|
101 * Mapping: |
|
|
102 * 1 -- acos(|x|>1) |
|
|
103 * 2 -- asin(|x|>1) |
|
|
104 * 3 -- atan2(+-0,+-0) |
|
|
105 * 4 -- hypot overflow |
|
|
106 * 5 -- cosh overflow |
|
|
107 * 6 -- exp overflow |
|
|
108 * 7 -- exp underflow |
|
|
109 * 8 -- y0(0) |
|
|
110 * 9 -- y0(-ve) |
|
|
111 * 10-- y1(0) |
|
|
112 * 11-- y1(-ve) |
|
|
113 * 12-- yn(0) |
|
|
114 * 13-- yn(-ve) |
|
|
115 * 14-- lgamma(finite) overflow |
|
|
116 * 15-- lgamma(-integer) |
|
|
117 * 16-- log(0) |
|
|
118 * 17-- log(x<0) |
|
|
119 * 18-- log10(0) |
|
|
120 * 19-- log10(x<0) |
|
|
121 * 20-- pow(0.0,0.0) |
|
|
122 * 21-- pow(x,y) overflow |
|
|
123 * 22-- pow(x,y) underflow |
|
|
124 * 23-- pow(0,negative) |
|
|
125 * 24-- pow(neg,non-integral) |
|
|
126 * 25-- sinh(finite) overflow |
|
|
127 * 26-- sqrt(negative) |
|
|
128 * 27-- fmod(x,0) |
|
|
129 * 28-- remainder(x,0) |
|
|
130 * 29-- acosh(x<1) |
|
|
131 * 30-- atanh(|x|>1) |
|
|
132 * 31-- atanh(|x|=1) |
|
|
133 * 32-- scalb overflow |
|
|
134 * 33-- scalb underflow |
|
|
135 * 34-- j0(|x|>X_TLOSS) |
|
|
136 * 35-- y0(x>X_TLOSS) |
|
|
137 * 36-- j1(|x|>X_TLOSS) |
|
|
138 * 37-- y1(x>X_TLOSS) |
|
|
139 * 38-- jn(|x|>X_TLOSS, n) |
|
|
140 * 39-- yn(x>X_TLOSS, n) |
|
|
141 * 40-- gamma(finite) overflow |
|
|
142 * 41-- gamma(-integer) |
|
|
143 * 42-- pow(NaN,0.0) |
|
|
144 * 43-- ldexp overflow |
|
|
145 * 44-- ldexp underflow |
|
|
146 */ |
|
|
147 |
|
|
148 |
|
|
149 double |
|
|
150 __kernel_standard(double x, double y, int type) |
|
|
151 { |
|
|
152 struct exception exc; |
|
|
153 |
|
|
154 #ifdef CYGSEM_LIBM_USE_STDERR |
|
|
155 (void) fflush(stdout); |
|
|
156 #endif |
|
|
157 exc.arg1 = x; |
|
|
158 exc.arg2 = y; |
|
|
159 switch(type) { |
|
|
160 case 1: |
|
|
161 /* acos(|x|>1) */ |
|
|
162 exc.type = DOMAIN; |
|
|
163 exc.name = "acos"; |
|
|
164 exc.retval = zero; |
|
|
165 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_POSIX) |
|
|
166 errno = EDOM; |
|
|
167 else if (!matherr(&exc)) { |
|
|
168 if(cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID) { |
|
|
169 (void) WRITE2("acos: DOMAIN error\n", 19); |
|
|
170 } |
|
|
171 errno = EDOM; |
|
|
172 } |
|
|
173 break; |
|
|
174 case 2: |
|
|
175 /* asin(|x|>1) */ |
|
|
176 exc.type = DOMAIN; |
|
|
177 exc.name = "asin"; |
|
|
178 exc.retval = zero; |
|
|
179 if(cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_POSIX) |
|
|
180 errno = EDOM; |
|
|
181 else if (!matherr(&exc)) { |
|
|
182 if(cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID) { |
|
|
183 (void) WRITE2("asin: DOMAIN error\n", 19); |
|
|
184 } |
|
|
185 errno = EDOM; |
|
|
186 } |
|
|
187 break; |
|
|
188 case 3: |
|
|
189 /* atan2(+-0,+-0) */ |
|
|
190 exc.arg1 = y; |
|
|
191 exc.arg2 = x; |
|
|
192 exc.type = DOMAIN; |
|
|
193 exc.name = "atan2"; |
|
|
194 exc.retval = zero; |
|
|
195 if(cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_POSIX) |
|
|
196 errno = EDOM; |
|
|
197 else if (!matherr(&exc)) { |
|
|
198 if(cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID) { |
|
|
199 (void) WRITE2("atan2: DOMAIN error\n", 20); |
|
|
200 } |
|
|
201 errno = EDOM; |
|
|
202 } |
|
|
203 break; |
|
|
204 case 4: |
|
|
205 /* hypot(finite,finite) overflow */ |
|
|
206 exc.type = OVERFLOW; |
|
|
207 exc.name = "hypot"; |
|
|
208 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID) |
|
|
209 exc.retval = HUGE; |
|
|
210 else |
|
|
211 exc.retval = HUGE_VAL; |
|
|
212 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_POSIX) |
|
|
213 errno = ERANGE; |
|
|
214 else if (!matherr(&exc)) { |
|
|
215 errno = ERANGE; |
|
|
216 } |
|
|
217 break; |
|
|
218 case 5: |
|
|
219 /* cosh(finite) overflow */ |
|
|
220 exc.type = OVERFLOW; |
|
|
221 exc.name = "cosh"; |
|
|
222 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID) |
|
|
223 exc.retval = HUGE; |
|
|
224 else |
|
|
225 exc.retval = HUGE_VAL; |
|
|
226 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_POSIX) |
|
|
227 errno = ERANGE; |
|
|
228 else if (!matherr(&exc)) { |
|
|
229 errno = ERANGE; |
|
|
230 } |
|
|
231 break; |
|
|
232 case 6: |
|
|
233 /* exp(finite) overflow */ |
|
|
234 exc.type = OVERFLOW; |
|
|
235 exc.name = "exp"; |
|
|
236 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID) |
|
|
237 exc.retval = HUGE; |
|
|
238 else |
|
|
239 exc.retval = HUGE_VAL; |
|
|
240 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_POSIX) |
|
|
241 errno = ERANGE; |
|
|
242 else if (!matherr(&exc)) { |
|
|
243 errno = ERANGE; |
|
|
244 } |
|
|
245 break; |
|
|
246 case 7: |
|
|
247 /* exp(finite) underflow */ |
|
|
248 exc.type = UNDERFLOW; |
|
|
249 exc.name = "exp"; |
|
|
250 exc.retval = zero; |
|
|
251 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_POSIX) |
|
|
252 errno = ERANGE; |
|
|
253 else if (!matherr(&exc)) { |
|
|
254 errno = ERANGE; |
|
|
255 } |
|
|
256 break; |
|
|
257 case 8: |
|
|
258 /* y0(0) = -inf */ |
|
|
259 exc.type = DOMAIN; /* should be SING for IEEE */ |
|
|
260 exc.name = "y0"; |
|
|
261 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID) |
|
|
262 exc.retval = -HUGE; |
|
|
263 else |
|
|
264 exc.retval = -HUGE_VAL; |
|
|
265 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_POSIX) |
|
|
266 errno = EDOM; |
|
|
267 else if (!matherr(&exc)) { |
|
|
268 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID) { |
|
|
269 (void) WRITE2("y0: DOMAIN error\n", 17); |
|
|
270 } |
|
|
271 errno = EDOM; |
|
|
272 } |
|
|
273 break; |
|
|
274 case 9: |
|
|
275 /* y0(x<0) = NaN */ |
|
|
276 exc.type = DOMAIN; |
|
|
277 exc.name = "y0"; |
|
|
278 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID) |
|
|
279 exc.retval = -HUGE; |
|
|
280 else |
|
|
281 exc.retval = -HUGE_VAL; |
|
|
282 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_POSIX) |
|
|
283 errno = EDOM; |
|
|
284 else if (!matherr(&exc)) { |
|
|
285 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID) { |
|
|
286 (void) WRITE2("y0: DOMAIN error\n", 17); |
|
|
287 } |
|
|
288 errno = EDOM; |
|
|
289 } |
|
|
290 break; |
|
|
291 case 10: |
|
|
292 /* y1(0) = -inf */ |
|
|
293 exc.type = DOMAIN; /* should be SING for IEEE */ |
|
|
294 exc.name = "y1"; |
|
|
295 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID) |
|
|
296 exc.retval = -HUGE; |
|
|
297 else |
|
|
298 exc.retval = -HUGE_VAL; |
|
|
299 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_POSIX) |
|
|
300 errno = EDOM; |
|
|
301 else if (!matherr(&exc)) { |
|
|
302 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID) { |
|
|
303 (void) WRITE2("y1: DOMAIN error\n", 17); |
|
|
304 } |
|
|
305 errno = EDOM; |
|
|
306 } |
|
|
307 break; |
|
|
308 case 11: |
|
|
309 /* y1(x<0) = NaN */ |
|
|
310 exc.type = DOMAIN; |
|
|
311 exc.name = "y1"; |
|
|
312 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID) |
|
|
313 exc.retval = -HUGE; |
|
|
314 else |
|
|
315 exc.retval = -HUGE_VAL; |
|
|
316 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_POSIX) |
|
|
317 errno = EDOM; |
|
|
318 else if (!matherr(&exc)) { |
|
|
319 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID) { |
|
|
320 (void) WRITE2("y1: DOMAIN error\n", 17); |
|
|
321 } |
|
|
322 errno = EDOM; |
|
|
323 } |
|
|
324 break; |
|
|
325 case 12: |
|
|
326 /* yn(n,0) = -inf */ |
|
|
327 exc.type = DOMAIN; /* should be SING for IEEE */ |
|
|
328 exc.name = "yn"; |
|
|
329 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID) |
|
|
330 exc.retval = -HUGE; |
|
|
331 else |
|
|
332 exc.retval = -HUGE_VAL; |
|
|
333 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_POSIX) |
|
|
334 errno = EDOM; |
|
|
335 else if (!matherr(&exc)) { |
|
|
336 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID) { |
|
|
337 (void) WRITE2("yn: DOMAIN error\n", 17); |
|
|
338 } |
|
|
339 errno = EDOM; |
|
|
340 } |
|
|
341 break; |
|
|
342 case 13: |
|
|
343 /* yn(x<0) = NaN */ |
|
|
344 exc.type = DOMAIN; |
|
|
345 exc.name = "yn"; |
|
|
346 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID) |
|
|
347 exc.retval = -HUGE; |
|
|
348 else |
|
|
349 exc.retval = -HUGE_VAL; |
|
|
350 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_POSIX) |
|
|
351 errno = EDOM; |
|
|
352 else if (!matherr(&exc)) { |
|
|
353 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID) { |
|
|
354 (void) WRITE2("yn: DOMAIN error\n", 17); |
|
|
355 } |
|
|
356 errno = EDOM; |
|
|
357 } |
|
|
358 break; |
|
|
359 case 14: |
|
|
360 /* lgamma(finite) overflow */ |
|
|
361 exc.type = OVERFLOW; |
|
|
362 exc.name = "lgamma"; |
|
|
363 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID) |
|
|
364 exc.retval = HUGE; |
|
|
365 else |
|
|
366 exc.retval = HUGE_VAL; |
|
|
367 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_POSIX) |
|
|
368 errno = ERANGE; |
|
|
369 else if (!matherr(&exc)) { |
|
|
370 errno = ERANGE; |
|
|
371 } |
|
|
372 break; |
|
|
373 case 15: |
|
|
374 /* lgamma(-integer) or lgamma(0) */ |
|
|
375 exc.type = SING; |
|
|
376 exc.name = "lgamma"; |
|
|
377 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID) |
|
|
378 exc.retval = HUGE; |
|
|
379 else |
|
|
380 exc.retval = HUGE_VAL; |
|
|
381 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_POSIX) |
|
|
382 errno = EDOM; |
|
|
383 else if (!matherr(&exc)) { |
|
|
384 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID) { |
|
|
385 (void) WRITE2("lgamma: SING error\n", 19); |
|
|
386 } |
|
|
387 errno = EDOM; |
|
|
388 } |
|
|
389 break; |
|
|
390 case 16: |
|
|
391 /* log(0) */ |
|
|
392 exc.type = SING; |
|
|
393 exc.name = "log"; |
|
|
394 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID) |
|
|
395 exc.retval = -HUGE; |
|
|
396 else |
|
|
397 exc.retval = -HUGE_VAL; |
|
|
398 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_POSIX) |
|
|
399 errno = ERANGE; |
|
|
400 else if (!matherr(&exc)) { |
|
|
401 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID) { |
|
|
402 (void) WRITE2("log: SING error\n", 16); |
|
|
403 } |
|
|
404 errno = EDOM; |
|
|
405 } |
|
|
406 break; |
|
|
407 case 17: |
|
|
408 /* log(x<0) */ |
|
|
409 exc.type = DOMAIN; |
|
|
410 exc.name = "log"; |
|
|
411 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID) |
|
|
412 exc.retval = -HUGE; |
|
|
413 else |
|
|
414 exc.retval = -HUGE_VAL; |
|
|
415 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_POSIX) |
|
|
416 errno = EDOM; |
|
|
417 else if (!matherr(&exc)) { |
|
|
418 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID) { |
|
|
419 (void) WRITE2("log: DOMAIN error\n", 18); |
|
|
420 } |
|
|
421 errno = EDOM; |
|
|
422 } |
|
|
423 break; |
|
|
424 case 18: |
|
|
425 /* log10(0) */ |
|
|
426 exc.type = SING; |
|
|
427 exc.name = "log10"; |
|
|
428 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID) |
|
|
429 exc.retval = -HUGE; |
|
|
430 else |
|
|
431 exc.retval = -HUGE_VAL; |
|
|
432 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_POSIX) |
|
|
433 errno = ERANGE; |
|
|
434 else if (!matherr(&exc)) { |
|
|
435 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID) { |
|
|
436 (void) WRITE2("log10: SING error\n", 18); |
|
|
437 } |
|
|
438 errno = EDOM; |
|
|
439 } |
|
|
440 break; |
|
|
441 case 19: |
|
|
442 /* log10(x<0) */ |
|
|
443 exc.type = DOMAIN; |
|
|
444 exc.name = "log10"; |
|
|
445 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID) |
|
|
446 exc.retval = -HUGE; |
|
|
447 else |
|
|
448 exc.retval = -HUGE_VAL; |
|
|
449 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_POSIX) |
|
|
450 errno = EDOM; |
|
|
451 else if (!matherr(&exc)) { |
|
|
452 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID) { |
|
|
453 (void) WRITE2("log10: DOMAIN error\n", 20); |
|
|
454 } |
|
|
455 errno = EDOM; |
|
|
456 } |
|
|
457 break; |
|
|
458 case 20: |
|
|
459 /* pow(0.0,0.0) */ |
|
|
460 /* error only if cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID */ |
|
|
461 exc.type = DOMAIN; |
|
|
462 exc.name = "pow"; |
|
|
463 exc.retval = zero; |
|
|
464 if (cyg_libm_get_compat_mode() != CYGNUM_LIBM_COMPAT_SVID) exc.retval = 1.0; |
|
|
465 else if (!matherr(&exc)) { |
|
|
466 (void) WRITE2("pow(0,0): DOMAIN error\n", 23); |
|
|
467 errno = EDOM; |
|
|
468 } |
|
|
469 break; |
|
|
470 case 21: |
|
|
471 /* pow(x,y) overflow */ |
|
|
472 exc.type = OVERFLOW; |
|
|
473 exc.name = "pow"; |
|
|
474 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID) { |
|
|
475 exc.retval = HUGE; |
|
|
476 y *= 0.5; |
|
|
477 if(x<zero&&rint(y)!=y) exc.retval = -HUGE; |
|
|
478 } else { |
|
|
479 exc.retval = HUGE_VAL; |
|
|
480 y *= 0.5; |
|
|
481 if(x<zero&&rint(y)!=y) exc.retval = -HUGE_VAL; |
|
|
482 } |
|
|
483 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_POSIX) |
|
|
484 errno = ERANGE; |
|
|
485 else if (!matherr(&exc)) { |
|
|
486 errno = ERANGE; |
|
|
487 } |
|
|
488 break; |
|
|
489 case 22: |
|
|
490 /* pow(x,y) underflow */ |
|
|
491 exc.type = UNDERFLOW; |
|
|
492 exc.name = "pow"; |
|
|
493 exc.retval = zero; |
|
|
494 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_POSIX) |
|
|
495 errno = ERANGE; |
|
|
496 else if (!matherr(&exc)) { |
|
|
497 errno = ERANGE; |
|
|
498 } |
|
|
499 break; |
|
|
500 case 23: |
|
|
501 /* 0**neg */ |
|
|
502 exc.type = DOMAIN; |
|
|
503 exc.name = "pow"; |
|
|
504 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID) |
|
|
505 exc.retval = zero; |
|
|
506 else |
|
|
507 exc.retval = -HUGE_VAL; |
|
|
508 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_POSIX) |
|
|
509 errno = EDOM; |
|
|
510 else if (!matherr(&exc)) { |
|
|
511 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID) { |
|
|
512 (void) WRITE2("pow(0,neg): DOMAIN error\n", 25); |
|
|
513 } |
|
|
514 errno = EDOM; |
|
|
515 } |
|
|
516 break; |
|
|
517 case 24: |
|
|
518 /* neg**non-integral */ |
|
|
519 exc.type = DOMAIN; |
|
|
520 exc.name = "pow"; |
|
|
521 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID) |
|
|
522 exc.retval = zero; |
|
|
523 else |
|
|
524 exc.retval = zero/zero; /* X/Open allow NaN */ |
|
|
525 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_POSIX) |
|
|
526 errno = EDOM; |
|
|
527 else if (!matherr(&exc)) { |
|
|
528 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID) { |
|
|
529 (void) WRITE2("neg**non-integral: DOMAIN error\n", 32); |
|
|
530 } |
|
|
531 errno = EDOM; |
|
|
532 } |
|
|
533 break; |
|
|
534 case 25: |
|
|
535 /* sinh(finite) overflow */ |
|
|
536 exc.type = OVERFLOW; |
|
|
537 exc.name = "sinh"; |
|
|
538 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID) |
|
|
539 exc.retval = ( (x>zero) ? HUGE : -HUGE); |
|
|
540 else |
|
|
541 exc.retval = ( (x>zero) ? HUGE_VAL : -HUGE_VAL); |
|
|
542 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_POSIX) |
|
|
543 errno = ERANGE; |
|
|
544 else if (!matherr(&exc)) { |
|
|
545 errno = ERANGE; |
|
|
546 } |
|
|
547 break; |
|
|
548 case 26: |
|
|
549 /* sqrt(x<0) */ |
|
|
550 exc.type = DOMAIN; |
|
|
551 exc.name = "sqrt"; |
|
|
552 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID) |
|
|
553 exc.retval = zero; |
|
|
554 else |
|
|
555 exc.retval = zero/zero; |
|
|
556 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_POSIX) |
|
|
557 errno = EDOM; |
|
|
558 else if (!matherr(&exc)) { |
|
|
559 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID) { |
|
|
560 (void) WRITE2("sqrt: DOMAIN error\n", 19); |
|
|
561 } |
|
|
562 errno = EDOM; |
|
|
563 } |
|
|
564 break; |
|
|
565 case 27: |
|
|
566 /* fmod(x,0) */ |
|
|
567 exc.type = DOMAIN; |
|
|
568 exc.name = "fmod"; |
|
|
569 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID) |
|
|
570 exc.retval = x; |
|
|
571 else |
|
|
572 exc.retval = zero/zero; |
|
|
573 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_POSIX) |
|
|
574 errno = EDOM; |
|
|
575 else if (!matherr(&exc)) { |
|
|
576 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID) { |
|
|
577 (void) WRITE2("fmod: DOMAIN error\n", 20); |
|
|
578 } |
|
|
579 errno = EDOM; |
|
|
580 } |
|
|
581 break; |
|
|
582 case 28: |
|
|
583 /* remainder(x,0) */ |
|
|
584 exc.type = DOMAIN; |
|
|
585 exc.name = "remainder"; |
|
|
586 exc.retval = zero/zero; |
|
|
587 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_POSIX) |
|
|
588 errno = EDOM; |
|
|
589 else if (!matherr(&exc)) { |
|
|
590 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID) { |
|
|
591 (void) WRITE2("remainder: DOMAIN error\n", 24); |
|
|
592 } |
|
|
593 errno = EDOM; |
|
|
594 } |
|
|
595 break; |
|
|
596 case 29: |
|
|
597 /* acosh(x<1) */ |
|
|
598 exc.type = DOMAIN; |
|
|
599 exc.name = "acosh"; |
|
|
600 exc.retval = zero/zero; |
|
|
601 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_POSIX) |
|
|
602 errno = EDOM; |
|
|
603 else if (!matherr(&exc)) { |
|
|
604 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID) { |
|
|
605 (void) WRITE2("acosh: DOMAIN error\n", 20); |
|
|
606 } |
|
|
607 errno = EDOM; |
|
|
608 } |
|
|
609 break; |
|
|
610 case 30: |
|
|
611 /* atanh(|x|>1) */ |
|
|
612 exc.type = DOMAIN; |
|
|
613 exc.name = "atanh"; |
|
|
614 exc.retval = zero/zero; |
|
|
615 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_POSIX) |
|
|
616 errno = EDOM; |
|
|
617 else if (!matherr(&exc)) { |
|
|
618 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID) { |
|
|
619 (void) WRITE2("atanh: DOMAIN error\n", 20); |
|
|
620 } |
|
|
621 errno = EDOM; |
|
|
622 } |
|
|
623 break; |
|
|
624 case 31: |
|
|
625 /* atanh(|x|=1) */ |
|
|
626 exc.type = SING; |
|
|
627 exc.name = "atanh"; |
|
|
628 exc.retval = x/zero; /* sign(x)*inf */ |
|
|
629 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_POSIX) |
|
|
630 errno = EDOM; |
|
|
631 else if (!matherr(&exc)) { |
|
|
632 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID) { |
|
|
633 (void) WRITE2("atanh: SING error\n", 18); |
|
|
634 } |
|
|
635 errno = EDOM; |
|
|
636 } |
|
|
637 break; |
|
|
638 case 32: |
|
|
639 /* scalb overflow; SVID also returns +-HUGE_VAL */ |
|
|
640 exc.type = OVERFLOW; |
|
|
641 exc.name = "scalb"; |
|
|
642 exc.retval = x > zero ? HUGE_VAL : -HUGE_VAL; |
|
|
643 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_POSIX) |
|
|
644 errno = ERANGE; |
|
|
645 else if (!matherr(&exc)) { |
|
|
646 errno = ERANGE; |
|
|
647 } |
|
|
648 break; |
|
|
649 case 33: |
|
|
650 /* scalb underflow */ |
|
|
651 exc.type = UNDERFLOW; |
|
|
652 exc.name = "scalb"; |
|
|
653 exc.retval = copysign(zero,x); |
|
|
654 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_POSIX) |
|
|
655 errno = ERANGE; |
|
|
656 else if (!matherr(&exc)) { |
|
|
657 errno = ERANGE; |
|
|
658 } |
|
|
659 break; |
|
|
660 case 34: |
|
|
661 /* j0(|x|>X_TLOSS) */ |
|
|
662 exc.type = TLOSS; |
|
|
663 exc.name = "j0"; |
|
|
664 exc.retval = zero; |
|
|
665 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_POSIX) |
|
|
666 errno = ERANGE; |
|
|
667 else if (!matherr(&exc)) { |
|
|
668 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID) { |
|
|
669 (void) WRITE2(exc.name, 2); |
|
|
670 (void) WRITE2(": TLOSS error\n", 14); |
|
|
671 } |
|
|
672 errno = ERANGE; |
|
|
673 } |
|
|
674 break; |
|
|
675 case 35: |
|
|
676 /* y0(x>X_TLOSS) */ |
|
|
677 exc.type = TLOSS; |
|
|
678 exc.name = "y0"; |
|
|
679 exc.retval = zero; |
|
|
680 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_POSIX) |
|
|
681 errno = ERANGE; |
|
|
682 else if (!matherr(&exc)) { |
|
|
683 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID) { |
|
|
684 (void) WRITE2(exc.name, 2); |
|
|
685 (void) WRITE2(": TLOSS error\n", 14); |
|
|
686 } |
|
|
687 errno = ERANGE; |
|
|
688 } |
|
|
689 break; |
|
|
690 case 36: |
|
|
691 /* j1(|x|>X_TLOSS) */ |
|
|
692 exc.type = TLOSS; |
|
|
693 exc.name = "j1"; |
|
|
694 exc.retval = zero; |
|
|
695 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_POSIX) |
|
|
696 errno = ERANGE; |
|
|
697 else if (!matherr(&exc)) { |
|
|
698 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID) { |
|
|
699 (void) WRITE2(exc.name, 2); |
|
|
700 (void) WRITE2(": TLOSS error\n", 14); |
|
|
701 } |
|
|
702 errno = ERANGE; |
|
|
703 } |
|
|
704 break; |
|
|
705 case 37: |
|
|
706 /* y1(x>X_TLOSS) */ |
|
|
707 exc.type = TLOSS; |
|
|
708 exc.name = "y1"; |
|
|
709 exc.retval = zero; |
|
|
710 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_POSIX) |
|
|
711 errno = ERANGE; |
|
|
712 else if (!matherr(&exc)) { |
|
|
713 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID) { |
|
|
714 (void) WRITE2(exc.name, 2); |
|
|
715 (void) WRITE2(": TLOSS error\n", 14); |
|
|
716 } |
|
|
717 errno = ERANGE; |
|
|
718 } |
|
|
719 break; |
|
|
720 case 38: |
|
|
721 /* jn(|x|>X_TLOSS) */ |
|
|
722 exc.type = TLOSS; |
|
|
723 exc.name = "jn"; |
|
|
724 exc.retval = zero; |
|
|
725 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_POSIX) |
|
|
726 errno = ERANGE; |
|
|
727 else if (!matherr(&exc)) { |
|
|
728 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID) { |
|
|
729 (void) WRITE2(exc.name, 2); |
|
|
730 (void) WRITE2(": TLOSS error\n", 14); |
|
|
731 } |
|
|
732 errno = ERANGE; |
|
|
733 } |
|
|
734 break; |
|
|
735 case 39: |
|
|
736 /* yn(x>X_TLOSS) */ |
|
|
737 exc.type = TLOSS; |
|
|
738 exc.name = "yn"; |
|
|
739 exc.retval = zero; |
|
|
740 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_POSIX) |
|
|
741 errno = ERANGE; |
|
|
742 else if (!matherr(&exc)) { |
|
|
743 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID) { |
|
|
744 (void) WRITE2(exc.name, 2); |
|
|
745 (void) WRITE2(": TLOSS error\n", 14); |
|
|
746 } |
|
|
747 errno = ERANGE; |
|
|
748 } |
|
|
749 break; |
|
|
750 case 40: |
|
|
751 /* gamma(finite) overflow */ |
|
|
752 exc.type = OVERFLOW; |
|
|
753 exc.name = "gamma"; |
|
|
754 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID) |
|
|
755 exc.retval = HUGE; |
|
|
756 else |
|
|
757 exc.retval = HUGE_VAL; |
|
|
758 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_POSIX) |
|
|
759 errno = ERANGE; |
|
|
760 else if (!matherr(&exc)) { |
|
|
761 errno = ERANGE; |
|
|
762 } |
|
|
763 break; |
|
|
764 case 41: |
|
|
765 /* gamma(-integer) or gamma(0) */ |
|
|
766 exc.type = SING; |
|
|
767 exc.name = "gamma"; |
|
|
768 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID) |
|
|
769 exc.retval = HUGE; |
|
|
770 else |
|
|
771 exc.retval = HUGE_VAL; |
|
|
772 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_POSIX) |
|
|
773 errno = EDOM; |
|
|
774 else if (!matherr(&exc)) { |
|
|
775 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID) { |
|
|
776 (void) WRITE2("gamma: SING error\n", 18); |
|
|
777 } |
|
|
778 errno = EDOM; |
|
|
779 } |
|
|
780 break; |
|
|
781 case 42: |
|
|
782 /* pow(NaN,0.0) */ |
|
|
783 /* error only if cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_SVID & CYGNUM_LIBM_COMPAT_XOPEN */ |
|
|
784 exc.type = DOMAIN; |
|
|
785 exc.name = "pow"; |
|
|
786 exc.retval = x; |
|
|
787 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_IEEE || |
|
|
788 cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_POSIX) exc.retval = 1.0; |
|
|
789 else if (!matherr(&exc)) { |
|
|
790 errno = EDOM; |
|
|
791 } |
|
|
792 break; |
|
|
793 case 43: |
|
|
794 /* ldexp overflow; SVID also returns +-HUGE_VAL */ |
|
|
795 exc.type = OVERFLOW; |
|
|
796 exc.name = "ldexp"; |
|
|
797 exc.retval = x > zero ? HUGE_VAL : -HUGE_VAL; |
|
|
798 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_POSIX) |
|
|
799 errno = ERANGE; |
|
|
800 else if (!matherr(&exc)) { |
|
|
801 errno = ERANGE; |
|
|
802 } |
|
|
803 break; |
|
|
804 case 44: |
|
|
805 /* ldexp underflow */ |
|
|
806 exc.type = UNDERFLOW; |
|
|
807 exc.name = "ldexp"; |
|
|
808 exc.retval = copysign(zero,x); |
|
|
809 if (cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_POSIX) |
|
|
810 errno = ERANGE; |
|
|
811 else if (!matherr(&exc)) { |
|
|
812 errno = ERANGE; |
|
|
813 } |
|
|
814 break; |
|
|
815 } |
|
|
816 return exc.retval; |
|
|
817 } |
|
|
818 |
|
|
819 #endif // ifdef CYGPKG_LIBM |
|
|
820 |
|
|
821 // EOF standard.c |