1: 2: 3:
4:
5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
15:
16: #include "math.h"
17: #include "math_private.h"
18:
19: static const volatile float huge = 1.0e+30, tiny = 1.0e-30;
20:
21: static const float
22: one = 1.0,
23: o_threshold = 8.8721679688e+01,
24: ln2_hi = 6.9313812256e-01,
25: ln2_lo = 9.0580006145e-06,
26: invln2 = 1.4426950216e+00,
27:
28: Q1 = -3.3333335072e-02,
29: Q2 = 1.5873016091e-03,
30: Q3 = -7.9365076090e-05,
31: Q4 = 4.0082177293e-06,
32: Q5 = -2.0109921195e-07;
33:
34: float
35: expm1f(float x)
36: {
37: float y,hi,lo,c,t,e,hxs,hfx,r1;
38: int32_t k,xsb;
39: u_int32_t hx;
40:
41: GET_FLOAT_WORD(hx,x);
42: xsb = hx&0x80000000;
43: if(xsb==0) y=x; else y= -x;
44: hx &= 0x7fffffff;
45:
46:
47: if(hx >= 0x4195b844) {
48: if(hx >= 0x42b17218) {
49: if(hx>0x7f800000)
50: return x+x;
51: if(hx==0x7f800000)
52: return (xsb==0)? x:-1.0;
53: if(x > o_threshold) return huge*huge;
54: }
55: if(xsb!=0) {
56: if(x+tiny<(float)0.0)
57: return tiny-one;
58: }
59: }
60:
61:
62: if(hx > 0x3eb17218) {
63: if(hx < 0x3F851592) {
64: if(xsb==0)
65: {hi = x - ln2_hi; lo = ln2_lo; k = 1;}
66: else
67: {hi = x + ln2_hi; lo = -ln2_lo; k = -1;}
68: } else {
69: k = invln2*x+((xsb==0)?(float)0.5:(float)-0.5);
70: t = k;
71: hi = x - t*ln2_hi;
72: lo = t*ln2_lo;
73: }
74: x = hi - lo;
75: c = (hi-x)-lo;
76: }
77: else if(hx < 0x33000000) {
78: t = huge+x;
79: return x - (t-(huge+x));
80: }
81: else k = 0;
82:
83:
84: hfx = (float)0.5*x;
85: hxs = x*hfx;
86: r1 = one+hxs*(Q1+hxs*(Q2+hxs*(Q3+hxs*(Q4+hxs*Q5))));
87: t = (float)3.0-r1*hfx;
88: e = hxs*((r1-t)/((float)6.0 - x*t));
89: if(k==0) return x - (x*e-hxs);
90: else {
91: e = (x*(e-c)-c);
92: e -= hxs;
93: if(k== -1) return (float)0.5*(x-e)-(float)0.5;
94: if(k==1)
95: if(x < (float)-0.25) return -(float)2.0*(e-(x+(float)0.5));
96: else return one+(float)2.0*(x-e);
97: if (k <= -2 || k>56) {
98: int32_t i;
99: y = one-(e-x);
100: GET_FLOAT_WORD(i,y);
101: SET_FLOAT_WORD(y,i+(k<<23));
102: return y-one;
103: }
104: t = one;
105: if(k<23) {
106: int32_t i;
107: SET_FLOAT_WORD(t,0x3f800000 - (0x1000000>>k));
108: y = t-(e-x);
109: GET_FLOAT_WORD(i,y);
110: SET_FLOAT_WORD(y,i+(k<<23));
111: } else {
112: int32_t i;
113: SET_FLOAT_WORD(t,((0x7f-k)<<23));
114: y = x-(e+t);
115: y += one;
116: GET_FLOAT_WORD(i,y);
117: SET_FLOAT_WORD(y,i+(k<<23));
118: }
119: }
120: return y;
121: }