MCPcopy Create free account
hub / github.com/emscripten-core/emscripten / tan_eval

Function tan_eval

system/lib/llvm-libc/src/math/generic/tan.cpp:38–72  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

36namespace {
37
38LIBC_INLINE double tan_eval(const DoubleDouble &u, DoubleDouble &result) {
39 // Evaluate tan(y) = tan(x - k * (pi/128))
40 // We use the degree-9 Taylor approximation:
41 // tan(y) ~ P(y) = y + y^3/3 + 2*y^5/15 + 17*y^7/315 + 62*y^9/2835
42 // Then the error is bounded by:
43 // |tan(y) - P(y)| < 2^-6 * |y|^11 < 2^-6 * 2^-66 = 2^-72.
44 // For y ~ u_hi + u_lo, fully expanding the polynomial and drop any terms
45 // < ulp(u_hi^3) gives us:
46 // P(y) = y + y^3/3 + 2*y^5/15 + 17*y^7/315 + 62*y^9/2835 = ...
47 // ~ u_hi + u_hi^3 * (1/3 + u_hi^2 * (2/15 + u_hi^2 * (17/315 +
48 // + u_hi^2 * 62/2835))) +
49 // + u_lo (1 + u_hi^2 * (1 + u_hi^2 * 2/3))
50 double u_hi_sq = u.hi * u.hi; // Error < ulp(u_hi^2) < 2^(-6 - 52) = 2^-58.
51 // p1 ~ 17/315 + u_hi^2 62 / 2835.
52 double p1 =
53 fputil::multiply_add(u_hi_sq, 0x1.664f4882c10fap-6, 0x1.ba1ba1ba1ba1cp-5);
54 // p2 ~ 1/3 + u_hi^2 2 / 15.
55 double p2 =
56 fputil::multiply_add(u_hi_sq, 0x1.1111111111111p-3, 0x1.5555555555555p-2);
57 // q1 ~ 1 + u_hi^2 * 2/3.
58 double q1 = fputil::multiply_add(u_hi_sq, 0x1.5555555555555p-1, 1.0);
59 double u_hi_3 = u_hi_sq * u.hi;
60 double u_hi_4 = u_hi_sq * u_hi_sq;
61 // p3 ~ 1/3 + u_hi^2 * (2/15 + u_hi^2 * (17/315 + u_hi^2 * 62/2835))
62 double p3 = fputil::multiply_add(u_hi_4, p1, p2);
63 // q2 ~ 1 + u_hi^2 * (1 + u_hi^2 * 2/3)
64 double q2 = fputil::multiply_add(u_hi_sq, q1, 1.0);
65 double tan_lo = fputil::multiply_add(u_hi_3, p3, u.lo * q2);
66 // Overall, |tan(y) - (u_hi + tan_lo)| < ulp(u_hi^3) <= 2^-71.
67 // And the relative errors is:
68 // |(tan(y) - (u_hi + tan_lo)) / tan(y) | <= 2*ulp(u_hi^2) < 2^-64
69 result = fputil::exact_add(u.hi, tan_lo);
70 return fputil::multiply_add(fputil::FPBits<double>(u_hi_3).abs().get_val(),
71 0x1.0p-51, 0x1.0p-102);
72}
73
74#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
75// Accurate evaluation of tan for small u.

Callers 1

LLVM_LIBC_FUNCTIONFunction · 0.85

Calls 3

multiply_addFunction · 0.85
get_valMethod · 0.45
absMethod · 0.45

Tested by

no test coverage detected