/* Core implementation of expd64(x). Separate into integer and fractional parts, where e^(i+f) == (e^i)*(e^f). We use a table lookup (expIntXDL(i)) for e^i and taylor series for e^f. Effectively: e^x = e^i * (1 + (x-i) + (((x-i)^2)/2!) + (((x-i)^3)/3!) + ...) The real expd64 will need add checks for NAN, INF and handle negative values of x. */ static DEC_TYPE IEEE_FUNCTION_NAME (DEC_TYPE val) { DEC_TYPE result, top, fraction, a, x, tp; DEC_TYPE t1, t2, t3, t4, t5, t6, t7, t8; DEC_TYPE t9, t10, t11, t12, t13, t14, t15, t16; DEC_TYPE t17, t18, t19, t20; long exp; long tmp; int neg = 0; if (__isinfd64(val)) { if (val < DFP_CONSTANT(0.0)) return DFP_CONSTANT(0.0); /* exp(-inf) = 0 */ else return val; /* exp(inf) = inf */ } if (val < DFP_CONSTANT(0.0)) { neg = 1; val = FUNC_D(__fabs) (val); } tmp = val; top = tmp; fraction = val - top; exp = tmp; if (fraction != 0.0DD) { a = top; x = val; t1 = (x - a); tp = t1 * t1; /* tp == ((x-a))^2 */ t2 = tp * __oneOverfactDD[2]; /* t2 == (((x-a))^2)/2! */ tp = tp * t1; /* tp == ((x-a))^3 */ t3 = tp * __oneOverfactDD[3]; /* t3 == (((x-a))^3)/3! */ tp = tp * t1; /* tp == ((x-a)/a)^4 */ t4 = tp * __oneOverfactDD[4]; /* t4 == (((x-a))^4)/4! */ tp = tp * t1; /* tp == ((x-a))^5 */ t5 = tp * __oneOverfactDD[5]; /* t5 == (((x-a))^5)/5! */ tp = tp * t1; /* tp == ((x-a))^6 */ t6 = tp * __oneOverfactDD[6]; /* t6 == (((x-a))^6)/6! */ tp = tp * t1; /* tp == ((x-a))^7 */ t7 = tp * __oneOverfactDD[7]; /* t7 == (((x-a))^7)/7! */ tp = tp * t1; /* tp == ((x-a))^8 */ t8 = tp * __oneOverfactDD[8]; /* t8 == (((x-a))^8)/8! */ if ( t8 > 1.0E-16DD) { tp = tp * t1; /* tp == ((x-a))^9 */ t9 = tp * __oneOverfactDD[9]; /* t9 == (((x-a))^9)/9! */ tp = tp * t1; /* tp == ((x-a))^10 */ t10 = tp * __oneOverfactDD[10]; /* t10 == (((x-a))^10)/10! */ tp = tp * t1; /* tp == ((x-a))^11 */ t11 = tp * __oneOverfactDD[11]; /* t12 == (((x-a))^11)/11! */ tp = tp * t1; /* tp == ((x-a))^12 */ t12 = tp * __oneOverfactDD[12]; /* t12 == (((x-a))^11)/12! */ if (t12 > 1.0E-16DD) { tp = tp * t1; /* tp == ((x-a))^13 */ t13 = tp * __oneOverfactDD[13]; /* t13 == (((x-a))^13)/13! */ tp = tp * t1; /* tp == ((x-a))^14 */ t14 = tp * __oneOverfactDD[14]; /* t14 == (((x-a))^14)/14! */ tp = tp * t1; /* tp == ((x-a))^15 */ t15 = tp * __oneOverfactDD[15]; /* t15 == (((x-a))^15)/15! */ tp = tp * t1; /* tp == ((x-a))^16 */ t16 = tp * __oneOverfactDD[16]; /* t16 == (((x-a))^16)/16! */ if (t12 > 1.0E-16DD) { tp = tp * t1; /* tp == ((x-a))^17 */ t17 = tp * __oneOverfactDD[17]; /* t17 == (((x-a))^17)/17! */ tp = tp * t1; /* tp == ((x-a))^18 */ t18 = tp * __oneOverfactDD[18]; /* t18 == (((x-a))^18)/18! */ tp = tp * t1; /* tp == ((x-a))^19 */ t19 = tp * __oneOverfactDD[19]; /* t19 == (((x-a))^19)/19! */ tp = tp * t1; /* tp == ((x-a))^20 */ t20 = tp * __oneOverfactDD[20]; /* t20 == (((x-a))^20)/20! */ tp = t19 + t20; tp = tp + t18; tp = tp + t17; tp = tp + t16; tp = tp + t15; } else { tp = t15 + t16; } tp = tp + t14; tp = tp + t13; tp = tp + t12; tp = tp + t11; } else { tp = t11 + t12; } tp = tp + t10; tp = tp + t9; tp = tp + t8; tp = tp + t7; } else tp = t7 + t8; /* now sum the terms from smallest to largest to avoid lose of percision */ tp = tp + t6; tp = tp + t5; tp = tp + t4; tp = tp + t3; tp = tp + t2; tp = tp + t1; tp = tp + 1.DD; if (exp!=0) result = __expIntXDL[exp] * tp; else result = tp; } else { if (exp!=0) result = __expIntXDL[exp]; else result = 1.DD; } if (neg) result = 1/result; return result; }
static DEC_TYPE IEEE_FUNCTION_NAME (DEC_TYPE val) { _Decimal64 result, top, fraction, a, x, tp; _Decimal64 t1, t2, t3, t4, t5, t6, t7, t8; _Decimal64 t9, t10, t11, t12, t13, t14, t15, t16; int exp; long tmp; if (__isnand64(val)) return val+val; if (val == DFP_CONSTANT(0.0)) { DFP_EXCEPT (FE_DIVBYZERO); return -DFP_HUGE_VAL; } if (val < DFP_CONSTANT(0.0)) { DFP_EXCEPT (FE_INVALID); return DFP_NAN; } if (__isinfd64(val)) return val; result = __frexpd64 (val, &exp); tmp = result * 100.0DD; top = tmp; top = top * 0.01DD; fraction = result - top; if (fraction != 0.00DD) { a = top; x = result; t1 = (x - a) / a; tp = t1 * t1; /* tp == ((x-a)/a)^2 */ t2 = tp / 2.0DD; /* t2 == (((x-a)/a)^2)/2 */ tp = tp * t1; /* tp == ((x-a)/a)^3 */ t3 = tp / 3.0DD; /* t3 == (((x-a)/a)^3)/3 */ tp = tp * t1; /* tp == ((x-a)/a)^4 */ t4 = tp / 4.0DD; /* t4 == (((x-a)/a)^4)/4 */ tp = tp * t1; /* tp == ((x-a)/a)^5 */ t5 = tp / 5.0DD; /* t5 == (((x-a)/a)^5)/5 */ tp = tp * t1; /* tp == ((x-a)/a)^6 */ t6 = tp / 6.0DD; /* t6 == (((x-a)/a)^6)/6 */ tp = tp * t1; /* tp == ((x-a)/a)^7 */ t7 = tp / 7.0DD; /* t7 == (((x-a)/a)^7)/7 */ tp = tp * t1; /* tp == ((x-a)/a)^8 */ t8 = tp / 8.0DD; /* t8 == (((x-a)/a)^8)/8 */ if ( t8 > 1.0E-16DD) { tp = tp * t1; /* tp == ((x-a)/a)^9 */ t9 = tp / 9.0DD; /* t9 == (((x-a)/a)^9)/9 */ tp = tp * t1; /* tp == ((x-a)/a)^10 */ t10 = tp / 10.0DD; /* t10 == (((x-a)/a)^10)/10 */ tp = tp * t1; /* tp == ((x-a)/a)^11 */ t11 = tp / 11.0DD; /* t12 == (((x-a)/a)^11)/11 */ tp = tp * t1; /* tp == ((x-a)/a)^12 */ t12 = tp / 12.0DD; /* t12 == (((x-a)/a)^11)/12 */ if (t12 > 1.0E-16DD) { tp = tp * t1; /* tp == ((x-a)/a)^13 */ t13 = tp / 13.0DD; /* t13 == (((x-a)/a)^13)/13 */ tp = tp * t1; /* tp == ((x-a)/a)^14 */ t14 = tp / 14.0DD; /* t14 == (((x-a)/a)^14)/14 */ tp = tp * t1; /* tp == ((x-a)/a)^15 */ t15 = tp / 15.0DD; /* t15 == (((x-a)/a)^15)/15 */ tp = tp * t1; /* tp == ((x-a)/a)^16 */ t16 = tp / 16.0DD; /* t16 == (((x-a)/a)^16)/16 */ tp = t15 - t16; tp = tp + (t13 - t14); tp = tp + (t11 - t12); } else { tp = t11 - t12; } tp = tp + (t9 - t10); tp = tp + (t7 - t8); } else tp = t7 - t8; /* now sum the terms from smallest to largest to avoid loss of percision */ tp = tp + (t5 - t6); tp = tp + (t3 - t4); tp = tp + (t1 - t2); if (exp!=0) result = (__LN_10 * exp) + __LN2digits[tmp] + tp; else result = __LN2digits[tmp] + tp; } else { if (exp!=0) result = (__LN_10 * exp) + __LN2digits[tmp]; else result = __LN2digits[tmp]; } return result; }