static floatx80 sincos_approximation(int neg, float128 r, Bit64u quotient, float_status_t &status) { if (quotient & 0x1) { r = poly_cos(r, status); neg = 0; } else { r = poly_sin(r, status); } floatx80 result = float128_to_floatx80(r, status); if (quotient & 0x2) neg = ! neg; if (neg) floatx80_chs(result); return result; }
static floatx80 sincos_approximation(int neg, float128 r, UINT64 quotient) { if (quotient & 0x1) { r = poly_cos(r); neg = 0; } else { r = poly_sin(r); } floatx80 result = float128_to_floatx80(r); if (quotient & 0x2) neg = ! neg; if (neg) result = floatx80_chs(result); return result; }
int ftan(floatx80 &a, float_status_t &status) { Bit64u aSig0, aSig1 = 0; Bit32s aExp, zExp, expDiff; int aSign, zSign; int q = 0; // handle unsupported extended double-precision floating encodings if (floatx80_is_unsupported(a)) { goto invalid; } aSig0 = extractFloatx80Frac(a); aExp = extractFloatx80Exp(a); aSign = extractFloatx80Sign(a); /* invalid argument */ if (aExp == 0x7FFF) { if ((Bit64u) (aSig0<<1)) { a = propagateFloatx80NaN(a, status); return 0; } invalid: float_raise(status, float_flag_invalid); a = floatx80_default_nan; return 0; } if (aExp == 0) { if (aSig0 == 0) return 0; float_raise(status, float_flag_denormal); /* handle pseudo denormals */ if (! (aSig0 & BX_CONST64(0x8000000000000000))) { float_raise(status, float_flag_inexact | float_flag_underflow); return 0; } normalizeFloatx80Subnormal(aSig0, &aExp, &aSig0); } zSign = aSign; zExp = EXP_BIAS; expDiff = aExp - zExp; /* argument is out-of-range */ if (expDiff >= 63) return -1; float_raise(status, float_flag_inexact); if (expDiff < -1) { // doesn't require reduction if (expDiff <= -68) { a = packFloatx80(aSign, aExp, aSig0); return 0; } zExp = aExp; } else { q = reduce_trig_arg(expDiff, zSign, aSig0, aSig1); } /* **************************** */ /* argument reduction completed */ /* **************************** */ /* using float128 for approximation */ float128 r = normalizeRoundAndPackFloat128(0, zExp-0x10, aSig0, aSig1, status); float128 sin_r = poly_sin(r, status); float128 cos_r = poly_cos(r, status); if (q & 0x1) { r = float128_div(cos_r, sin_r, status); zSign = ! zSign; } else { r = float128_div(sin_r, cos_r, status); } a = float128_to_floatx80(r, status); if (zSign) floatx80_chs(a); return 0; }
int floatx80_ftan(floatx80 &a) { UINT64 aSig0, aSig1 = 0; INT32 aExp, zExp, expDiff; int aSign, zSign; int q = 0; aSig0 = extractFloatx80Frac(a); aExp = extractFloatx80Exp(a); aSign = extractFloatx80Sign(a); /* invalid argument */ if (aExp == 0x7FFF) { if ((UINT64) (aSig0<<1)) { a = propagateFloatx80NaNOneArg(a); return 0; } float_raise(float_flag_invalid); a = floatx80_default_nan; return 0; } if (aExp == 0) { if (aSig0 == 0) return 0; // float_raise(float_flag_denormal); /* handle pseudo denormals */ if (! (aSig0 & U64(0x8000000000000000))) { float_raise(float_flag_inexact | float_flag_underflow); return 0; } normalizeFloatx80Subnormal(aSig0, &aExp, &aSig0); } zSign = aSign; zExp = EXP_BIAS; expDiff = aExp - zExp; /* argument is out-of-range */ if (expDiff >= 63) return -1; float_raise(float_flag_inexact); if (expDiff < -1) { // doesn't require reduction if (expDiff <= -68) { a = packFloatx80(aSign, aExp, aSig0); return 0; } zExp = aExp; } else { q = reduce_trig_arg(expDiff, zSign, aSig0, aSig1); } /* **************************** */ /* argument reduction completed */ /* **************************** */ /* using float128 for approximation */ float128 r = normalizeRoundAndPackFloat128(0, zExp-0x10, aSig0, aSig1); float128 sin_r = poly_sin(r); float128 cos_r = poly_cos(r); if (q & 0x1) { r = float128_div(cos_r, sin_r); zSign = ! zSign; } else { r = float128_div(sin_r, cos_r); } a = float128_to_floatx80(r); if (zSign) a = floatx80_chs(a); return 0; }