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

Function exp2_denorm

system/lib/llvm-libc/src/math/generic/exp2.cpp:156–201  ·  view source on GitHub ↗

When output is denormal.

Source from the content-addressed store, hash-verified

154
155// When output is denormal.
156double exp2_denorm(double x) {
157 // Range reduction.
158 int k =
159 static_cast<int>(cpp::bit_cast<uint64_t>(x + 0x1.8000'0000'4p21) >> 19);
160 double kd = static_cast<double>(k);
161
162 uint32_t idx1 = (k >> 6) & 0x3f;
163 uint32_t idx2 = k & 0x3f;
164
165 int hi = k >> 12;
166
167 DoubleDouble exp_mid1{EXP2_MID1[idx1].mid, EXP2_MID1[idx1].hi};
168 DoubleDouble exp_mid2{EXP2_MID2[idx2].mid, EXP2_MID2[idx2].hi};
169 DoubleDouble exp_mid = fputil::quick_mult(exp_mid1, exp_mid2);
170
171 // |dx| < 2^-13 + 2^-30.
172 double dx = fputil::multiply_add(kd, -0x1.0p-12, x); // exact
173
174 double mid_lo = dx * exp_mid.hi;
175
176 // Approximate (2^dx - 1)/dx ~ 1 + a0*dx + a1*dx^2 + a2*dx^3 + a3*dx^4.
177 double p = poly_approx_d(dx);
178
179 double lo = fputil::multiply_add(p, mid_lo, exp_mid.lo);
180
181#ifdef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
182 return ziv_test_denorm</*SKIP_ZIV_TEST=*/true>(hi, exp_mid.hi, lo, ERR_D)
183 .value();
184#else
185 if (auto r = ziv_test_denorm(hi, exp_mid.hi, lo, ERR_D);
186 LIBC_LIKELY(r.has_value()))
187 return r.value();
188
189 // Use double-double
190 DoubleDouble r_dd = exp2_double_double(dx, exp_mid);
191
192 if (auto r = ziv_test_denorm(hi, r_dd.hi, r_dd.lo, ERR_DD);
193 LIBC_LIKELY(r.has_value()))
194 return r.value();
195
196 // Use 128-bit precision
197 Float128 r_f128 = exp2_f128(dx, hi, idx1, idx2);
198
199 return static_cast<double>(r_f128);
200#endif // LIBC_MATH_HAS_SKIP_ACCURATE_PASS
201}
202
203// Check for exceptional cases when:
204// * log2(1 - 2^-54) < x < log2(1 + 2^-53)

Callers 1

set_exceptionalFunction · 0.85

Calls 6

multiply_addFunction · 0.85
exp2_double_doubleFunction · 0.85
exp2_f128Function · 0.85
poly_approx_dFunction · 0.70
valueMethod · 0.45
has_valueMethod · 0.45

Tested by

no test coverage detected