Rev 1906 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1906 | Rev 3362 | ||
---|---|---|---|
Line 1... | Line 1... | ||
1 | /* @(#)s_erf.c 1.3 95/01/18 */ |
1 | /* @(#)s_erf.c 5.1 93/09/24 */ |
2 | /* |
2 | /* |
3 | * ==================================================== |
3 | * ==================================================== |
4 | * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. |
4 | * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. |
5 | * |
5 | * |
6 | * Developed at SunSoft, a Sun Microsystems, Inc. business. |
6 | * Developed at SunPro, a Sun Microsystems, Inc. business. |
7 | * Permission to use, copy, modify, and distribute this |
7 | * Permission to use, copy, modify, and distribute this |
8 | * software is freely granted, provided that this notice |
8 | * software is freely granted, provided that this notice |
9 | * is preserved. |
9 | * is preserved. |
10 | * ==================================================== |
10 | * ==================================================== |
11 | */ |
11 | */ |
Line -... | Line 12... | ||
- | 12 | ||
- | 13 | /* |
|
- | 14 | FUNCTION |
|
- | 15 | < |
|
- | 16 | INDEX |
|
- | 17 | erf |
|
- | 18 | INDEX |
|
- | 19 | erff |
|
- | 20 | INDEX |
|
- | 21 | erfc |
|
- | 22 | INDEX |
|
- | 23 | erfcf |
|
- | 24 | ||
- | 25 | ANSI_SYNOPSIS |
|
- | 26 | #include |
|
- | 27 | double erf(double <[x]>); |
|
- | 28 | float erff(float <[x]>); |
|
- | 29 | double erfc(double <[x]>); |
|
- | 30 | float erfcf(float <[x]>); |
|
- | 31 | TRAD_SYNOPSIS |
|
- | 32 | #include |
|
- | 33 | ||
- | 34 | double erf(<[x]>) |
|
- | 35 | double <[x]>; |
|
- | 36 | ||
- | 37 | float erff(<[x]>) |
|
- | 38 | float <[x]>; |
|
- | 39 | ||
- | 40 | double erfc(<[x]>) |
|
- | 41 | double <[x]>; |
|
- | 42 | ||
- | 43 | float erfcf(<[x]>) |
|
- | 44 | float <[x]>; |
|
- | 45 | ||
- | 46 | DESCRIPTION |
|
- | 47 | < |
|
- | 48 | which estimates the probability that an observation will fall within |
|
- | 49 | <[x]> standard deviations of the mean (assuming a normal |
|
- | 50 | distribution). |
|
- | 51 | @tex |
|
- | 52 | The error function is defined as |
|
- | 53 | $${2\over\sqrt\pi}\times\int_0^x e^{-t^2}dt$$ |
|
- | 54 | @end tex |
|
- | 55 | ||
- | 56 | < |
|
- | 57 | < |
|
- | 58 | so that you can use it to avoid the loss of precision that would |
|
- | 59 | result from subtracting large probabilities (on large <[x]>) from 1. |
|
- | 60 | ||
- | 61 | < |
|
- | 62 | argument and result types. |
|
- | 63 | ||
- | 64 | RETURNS |
|
- | 65 | For positive arguments, < |
|
- | 66 | probability---a number between 0 and 1. |
|
- | 67 | ||
- | 68 | PORTABILITY |
|
- | 69 | None of the variants of < |
|
- | 70 | */ |
|
12 | 71 | ||
13 | /* double erf(double x) |
72 | /* double erf(double x) |
14 | * double erfc(double x) |
73 | * double erfc(double x) |
15 | * x |
74 | * x |
16 | * 2 |\ |
75 | * 2 |\ |
Line 104... | Line 163... | ||
104 | * erfc/erf(NaN) is NaN |
163 | * erfc/erf(NaN) is NaN |
105 | */ |
164 | */ |
106 | 165 | ||
Line 107... | Line 166... | ||
107 | 166 | ||
108 | /* #include "fdlibm.h" */ |
- | |
109 | - | ||
110 | #include |
- | |
111 | #include |
- | |
112 | #include |
- | |
113 | - | ||
114 | #define __ieee754_exp exp |
- | |
115 | - | ||
116 | typedef union |
- | |
117 | { |
- | |
118 | double value; |
- | |
119 | struct |
- | |
120 | { |
- | |
121 | uint32_t lsw; |
- | |
122 | uint32_t msw; |
- | |
123 | } parts; |
- | |
124 | } ieee_double_shape_type; |
- | |
125 | - | ||
126 | - | ||
127 | static inline int __get_hi_word(const double x) |
- | |
128 | { |
- | |
129 | ieee_double_shape_type u; |
- | |
130 | u.value = x; |
- | |
131 | return u.parts.msw; |
- | |
132 | } |
- | |
133 | - | ||
134 | static inline void __trunc_lo_word(double *x) |
- | |
135 | { |
- | |
136 | ieee_double_shape_type u; |
- | |
137 | u.value = *x; |
- | |
138 | u.parts.lsw = 0; |
- | |
139 | *x = u.value; |
- | |
Line -... | Line 167... | ||
- | 167 | #include "fdlibm.h" |
|
Line 140... | Line 168... | ||
140 | } |
168 | |
141 | 169 | #ifndef _DOUBLE_IS_32BITS |
|
142 | 170 | ||
143 | #ifdef __STDC__ |
171 | #ifdef __STDC__ |
Line 225... | Line 253... | ||
225 | double erf(x) |
253 | double erf(x) |
226 | double x; |
254 | double x; |
227 | #endif |
255 | #endif |
228 | { |
256 | { |
229 | int hx,ix,i; |
257 | __int32_t hx,ix,i; |
230 | double R,S,P,Q,s,y,z,r; |
258 | double R,S,P,Q,s,y,z,r; |
231 | hx = __get_hi_word(x); |
259 | GET_HIGH_WORD(hx,x); |
232 | ix = hx&0x7fffffff; |
260 | ix = hx&0x7fffffff; |
233 | if(ix>=0x7ff00000) { /* erf(nan)=nan */ |
261 | if(ix>=0x7ff00000) { /* erf(nan)=nan */ |
234 | i = ((unsigned)hx>>31)<<1; |
262 | i = ((__uint32_t)hx>>31)<<1; |
235 | return (double)(1-i)+one/x; /* erf(+-inf)=+-1 */ |
263 | return (double)(1-i)+one/x; /* erf(+-inf)=+-1 */ |
236 | } |
264 | } |
237 | 265 | ||
Line 238... | Line 266... | ||
238 | if(ix < 0x3feb0000) { /* |x|<0.84375 */ |
266 | if(ix < 0x3feb0000) { /* |x|<0.84375 */ |
239 | if(ix < 0x3e300000) { /* |x|<2**-28 */ |
267 | if(ix < 0x3e300000) { /* |x|<2**-28 */ |
Line 269... | Line 297... | ||
269 | S=one+s*(sb1+s*(sb2+s*(sb3+s*(sb4+s*( |
297 | S=one+s*(sb1+s*(sb2+s*(sb3+s*(sb4+s*( |
270 | sb5+s*(sb6+s*sb7)))))); |
298 | sb5+s*(sb6+s*sb7)))))); |
271 | } |
299 | } |
272 | z = x; |
300 | z = x; |
273 | __trunc_lo_word(&z); |
301 | SET_LOW_WORD(z,0); |
274 | r = __ieee754_exp(-z*z-0.5625)*__ieee754_exp((z-x)*(z+x)+R/S); |
302 | r = __ieee754_exp(-z*z-0.5625)*__ieee754_exp((z-x)*(z+x)+R/S); |
275 | if(hx>=0) return one-r/x; else return r/x-one; |
303 | if(hx>=0) return one-r/x; else return r/x-one; |
276 | } |
304 | } |
277 | 305 | ||
Line 278... | Line 306... | ||
278 | #ifdef __STDC__ |
306 | #ifdef __STDC__ |
Line 281... | Line 309... | ||
281 | double erfc(x) |
309 | double erfc(x) |
282 | double x; |
310 | double x; |
283 | #endif |
311 | #endif |
284 | { |
312 | { |
285 | int hx,ix; |
313 | __int32_t hx,ix; |
286 | double R,S,P,Q,s,y,z,r; |
314 | double R,S,P,Q,s,y,z,r; |
287 | hx = __get_hi_word(x); |
315 | GET_HIGH_WORD(hx,x); |
288 | ix = hx&0x7fffffff; |
316 | ix = hx&0x7fffffff; |
289 | if(ix>=0x7ff00000) { /* erfc(nan)=nan */ |
317 | if(ix>=0x7ff00000) { /* erfc(nan)=nan */ |
290 | /* erfc(+-inf)=0,2 */ |
318 | /* erfc(+-inf)=0,2 */ |
291 | return (double)(((unsigned)hx>>31)<<1)+one/x; |
319 | return (double)(((__uint32_t)hx>>31)<<1)+one/x; |
292 | } |
320 | } |
293 | 321 | ||
Line 294... | Line 322... | ||
294 | if(ix < 0x3feb0000) { /* |x|<0.84375 */ |
322 | if(ix < 0x3feb0000) { /* |x|<0.84375 */ |
295 | if(ix < 0x3c700000) /* |x|<2**-56 */ |
323 | if(ix < 0x3c700000) /* |x|<2**-56 */ |
296 | return one-x; |
324 | return one-x; |
Line 331... | Line 359... | ||
331 | S=one+s*(sb1+s*(sb2+s*(sb3+s*(sb4+s*( |
359 | S=one+s*(sb1+s*(sb2+s*(sb3+s*(sb4+s*( |
332 | sb5+s*(sb6+s*sb7)))))); |
360 | sb5+s*(sb6+s*sb7)))))); |
333 | } |
361 | } |
334 | z = x; |
362 | z = x; |
335 | __trunc_lo_word(&z); |
363 | SET_LOW_WORD(z,0); |
336 | r = __ieee754_exp(-z*z-0.5625)* |
364 | r = __ieee754_exp(-z*z-0.5625)* |
337 | __ieee754_exp((z-x)*(z+x)+R/S); |
365 | __ieee754_exp((z-x)*(z+x)+R/S); |
338 | if(hx>0) return r/x; else return two-r/x; |
366 | if(hx>0) return r/x; else return two-r/x; |
339 | } else { |
367 | } else { |
340 | /* set range error */ |
368 | if(hx>0) return tiny*tiny; else return two-tiny; |
341 | errno = ERANGE; |
- | |
342 | if(hx>0) return tiny*tiny; else return two-tiny; |
- | |
343 | } |
369 | } |
344 | }>0&&ix>>>28>>>=>>1/4>>2**-56>>0.84375>>1)+one/x; |
370 | } |
345 | ><1)+one/x; |
371 | |
- | 372 | #endif /* _DOUBLE_IS_32BITS */>0&&ix>>>28>>>=>>1/4>>2**-56>>0.84375>>1)+one/x; |
|
- | 373 | ><1)+one/x; |