DEC_TYPE INTERNAL_FUNCTION_NAME (DEC_TYPE x) { DEC_TYPE z = IEEE_FUNCTION_NAME (x); if (!FUNC_D(__isfinite) (z) && FUNC_D(__isfinite) (x)) DFP_ERRNO (ERANGE); return z; }
__ROUND_RETURN_TYPE INTERNAL_FUNCTION_NAME (DEC_TYPE x) { __ROUND_RETURN_TYPE z = IEEE_FUNCTION_NAME (x); if (FUNC_D(__isnan) (x) || FUNC_D(__isinf) (x) || x > __MAX_VALUE || x < __MIN_VALUE) DFP_ERRNO (EDOM); return z; }
DEC_TYPE INTERNAL_FUNCTION_NAME (DEC_TYPE x) { DEC_TYPE z = IEEE_FUNCTION_NAME (x); if (!FUNC_D(__isfinite) (z) && FUNC_D(__isfinite) (x)) DFP_ERRNO (ERANGE); if (x < DFP_CONSTANT(0.0) && (FUNC_D (__isinf) (x) && FUNC_D (__rint) (x) == x) ) DFP_ERRNO (EDOM); return z; }
static DEC_TYPE IEEE_FUNCTION_NAME (DEC_TYPE x, int y) { DEC_TYPE result; long newexp; #if NUMDIGITS_SUPPORT==1 newexp = FUNC_D (getexp) (x) + y + 1; if (newexp > PASTE(DECIMAL,PASTE(_DECIMAL_SIZE,_Emax))) { result = DFP_HUGE_VAL; DFP_EXCEPT (FE_OVERFLOW); } else if (newexp < PASTE(DECIMAL,PASTE(_DECIMAL_SIZE,_Emin))) { result = -DFP_HUGE_VAL; DFP_EXCEPT (FE_OVERFLOW); } else result = FUNC_D(setexp) (x, newexp); #else decContext context; decNumber dn_x; FUNC_CONVERT_TO_DN (&x, &dn_x); if (___decNumberIsNaN (&dn_x) || ___decNumberIsZero (&dn_x) || ___decNumberIsInfinite (&dn_x)) return x+x; if (y == 0) return x; /* ldexp(x,y) is just x*10**y, which is equivalent to increasing the exponent * by y + 1. */ newexp = dn_x.exponent + y + 1; if(newexp > INT_MAX) newexp = INT_MAX; if(newexp < -INT_MAX) newexp = -INT_MAX; dn_x.exponent = newexp; decContextDefault (&context, DEFAULT_CONTEXT); FUNC_CONVERT_FROM_DN (&dn_x, &result, &context); if (context.status & DEC_Overflow) DFP_EXCEPT (FE_OVERFLOW); #endif return result; }
DEC_TYPE INTERNAL_FUNCTION_NAME (DEC_TYPE x, DEC_TYPE y) { DEC_TYPE z = IEEE_FUNCTION_NAME (x, y); /* Pole error: x = 0, y < 0 (non-inf). Set ERANGE in accordance with C99 */ if (x == DFP_CONSTANT(0.0) && FUNC_D(__isfinite)(y) && y < DFP_CONSTANT(0.0)) DFP_ERRNO (ERANGE); if (!FUNC_D(__isfinite) (z) && FUNC_D(__isfinite) (x) && FUNC_D(__isfinite) (y)) { if (FUNC_D(__isnan) (z)) /* Domain error was triggered, x < 0 and y was not an odd int */ DFP_ERRNO (EDOM); else /* Overflow */ DFP_ERRNO (ERANGE); } return z; }
static DEC_TYPE IEEE_FUNCTION_NAME (DEC_TYPE x) { DEC_TYPE result, gamma; int local_signgam; if (x == DFP_CONSTANT(0.0)) /* Pole error if x== +-0 */ { DFP_EXCEPT (FE_DIVBYZERO); // return FUNC_D (__builtin_signbit) (x) ? -DFP_HUGE_VAL : DFP_HUGE_VAL; return (x<0) ? -DFP_HUGE_VAL : DFP_HUGE_VAL; } if (x < DFP_CONSTANT(0.0) && (!FUNC_D (__isinf) (x) && FUNC_D (__rint) (x) == x) ) { DFP_EXCEPT (FE_INVALID); return DFP_NAN; } gamma = FUNC_D(__lgamma_r) (x,&local_signgam); result = local_signgam * FUNC_D(__exp) (gamma); return result; }
DEC_TYPE INTERNAL_FUNCTION_NAME (DEC_TYPE x) { int e, rem, sign; _Decimal128 z; if (! FUNC_D(__isfinite) (x)) /* cbrt(x:x=inf/nan/-inf) = x+x (for sNaN) */ return x + x; if (x == DFP_CONSTANT(0.0)) /* cbrt(0) = 0 */ return (x); if (x > DFP_CONSTANT(0.0)) sign = 1; else { sign = -1; x = -x; } z = x; /* extract power of 2, leaving mantissa between 0.5 and 1 */ x = FUNC_D(__frexp) (x, &e); /* Approximate cube root of number between .5 and 1, peak relative error = 1.2e-6 */ x = ((((1.3584464340920900529734e-1DL * x - 6.3986917220457538402318e-1DL) * x + 1.2875551670318751538055e0DL) * x - 1.4897083391357284957891e0DL) * x + 1.3304961236013647092521e0DL) * x + 3.7568280825958912391243e-1DL; /* exponent divided by 3 */ if (e >= 0) { rem = e; e /= 3; rem -= 3 * e; if (rem == 1) //x *= CBRT2; x *= CBRT10; else if (rem == 2) //x *= CBRT4; x *= CBRT100; } else { /* argument less than 1 */ e = -e; rem = e; e /= 3; rem -= 3 * e; if (rem == 1) //x *= CBRT2I; x *= CBRT10I; else if (rem == 2) //x *= CBRT4I; x *= CBRT100I; e = -e; } /* multiply by power of 2 */ x = FUNC_D(__ldexp) (x, e); /* Newton iteration */ x -= (x - (z / (x * x))) * 0.3333333333333333333333333333333333333333DL; x -= (x - (z / (x * x))) * 0.3333333333333333333333333333333333333333DL; x -= (x - (z / (x * x))) * 0.3333333333333333333333333333333333333333DL; if (sign < 0) x = -x; return (x); }
/* 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; }
int INTERNAL_FUNCTION_NAME (DEC_TYPE x, DEC_TYPE y) { return FUNC_D(__isnan) (x) || FUNC_D(__isnan) (y); }
static DEC_TYPE IEEE_FUNCTION_NAME (DEC_TYPE x) { _Decimal128 z, r, w, p, q, s, t, f2, ix; int32_t sign; if(isnan(x)) return x+x; sign = (x > 0.0DL)?0:1; ix = FUNC_D(__fabs) (x); if (ix >= 1.0DL) /* |x| >= 1 */ { if (ix == 1.0DL) { /* |x| == 1 */ if (sign == 0) return (DEC_TYPE)(0.0DL); /* acos(1) = 0 */ else return (DEC_TYPE)((2.0DL * pio2_hi) + (2.0DL * pio2_lo)); /* acos(-1)= pi */ } /* acos(|x| > 1) is NaN */ DFP_EXCEPT (FE_INVALID); return DFP_NAN; } else if (ix < 0.5DL) /* |x| < 0.5 */ { /* |x| < 2**-57 */ if (ix < 0.000000000000000000000000000000000000000000000000000000002DL) return (DEC_TYPE)(pio2_hi + pio2_lo); //Should raise INEXACT if (ix < 0.4375DL) /* |x| < .4375 */ { /* Arcsine of x. */ z = x * x; p = (((((((((pS9 * z + pS8) * z + pS7) * z + pS6) * z + pS5) * z + pS4) * z + pS3) * z + pS2) * z + pS1) * z + pS0) * z; q = (((((((( z + qS8) * z + qS7) * z + qS6) * z + qS5) * z + qS4) * z + qS3) * z + qS2) * z + qS1) * z + qS0; r = x + x * p / q; z = pio2_hi - (r - pio2_lo); return (DEC_TYPE)z; } /* .4375 <= |x| < .5 */ t = ix - 0.4375DL; p = ((((((((((P10 * t + P9) * t + P8) * t + P7) * t + P6) * t + P5) * t + P4) * t + P3) * t + P2) * t + P1) * t + P0) * t; q = (((((((((t + Q9) * t + Q8) * t + Q7) * t + Q6) * t + Q5) * t + Q4) * t + Q3) * t + Q2) * t + Q1) * t + Q0; r = p / q; if (sign) r = pimacosr4375 - r; else r = acosr4375 + r; return (DEC_TYPE)r; } else if (ix < 0.625DL) /* |x| < 0.625 */ { t = ix - 0.5625DL; p = ((((((((((rS10 * t + rS9) * t + rS8) * t + rS7) * t + rS6) * t + rS5) * t + rS4) * t + rS3) * t + rS2) * t + rS1) * t + rS0) * t; q = (((((((((t + sS9) * t + sS8) * t + sS7) * t + sS6) * t + sS5) * t + sS4) * t + sS3) * t + sS2) * t + sS1) * t + sS0; if (sign) r = pimacosr5625 - p / q; else r = acosr5625 + p / q; return (DEC_TYPE)r; } else { /* |x| >= .625 */ z = (one - ix) * 0.5DL; s = __sqrtd128 (z); /* Compute an extended precision square root from the Newton iteration s -> 0.5 * (s + z / s). The change w from s to the improved value is w = 0.5 * (s + z / s) - s = (s^2 + z)/2s - s = (z - s^2)/2s. Express s = f1 + f2 where f1 * f1 is exactly representable. w = (z - s^2)/2s = (z - f1^2 - 2 f1 f2 - f2^2)/2s . s + w has extended precision. */ p = s; /* u.value = s; u.parts32.w2 = 0; u.parts32.w3 = 0; */ f2 = s - p; w = z - p * p; w = w - 2.0DL * p * f2; w = w - f2 * f2; w = w / (2.0DL * s); /* Arcsine of s. */ p = (((((((((pS9 * z + pS8) * z + pS7) * z + pS6) * z + pS5) * z + pS4) * z + pS3) * z + pS2) * z + pS1) * z + pS0) * z; q = (((((((( z + qS8) * z + qS7) * z + qS6) * z + qS5) * z + qS4) * z + qS3) * z + qS2) * z + qS1) * z + qS0; r = s + (w + s * p / q); if (sign) w = pio2_hi + (pio2_lo - r); else w = r; return (DEC_TYPE)(2.0DL * w); } }
int PREFIXED_FUNCTION_NAME (DEC_TYPE x, DEC_TYPE y) { return FUNC_D(__isnan) (x) || FUNC_D(__isnan) (y); }