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

Function exp10_denorm

system/lib/llvm-libc/src/math/generic/exp10.cpp:183–229  ·  view source on GitHub ↗

When output is denormal.

Source from the content-addressed store, hash-verified

181
182// When output is denormal.
183double exp10_denorm(double x) {
184 // Range reduction.
185 double tmp = fputil::multiply_add(x, LOG2_10, 0x1.8000'0000'4p21);
186 int k = static_cast<int>(cpp::bit_cast<uint64_t>(tmp) >> 19);
187 double kd = static_cast<double>(k);
188
189 uint32_t idx1 = (k >> 6) & 0x3f;
190 uint32_t idx2 = k & 0x3f;
191
192 int hi = k >> 12;
193
194 DoubleDouble exp_mid1{EXP2_MID1[idx1].mid, EXP2_MID1[idx1].hi};
195 DoubleDouble exp_mid2{EXP2_MID2[idx2].mid, EXP2_MID2[idx2].hi};
196 DoubleDouble exp_mid = fputil::quick_mult(exp_mid1, exp_mid2);
197
198 // |dx| < 1.5 * 2^-15 + 2^-31 < 2^-14
199 double lo_h = fputil::multiply_add(kd, MLOG10_2_EXP2_M12_HI, x); // exact
200 double dx = fputil::multiply_add(kd, MLOG10_2_EXP2_M12_MID, lo_h);
201
202 double mid_lo = dx * exp_mid.hi;
203
204 // Approximate (10^dx - 1)/dx ~ 1 + a0*dx + a1*dx^2 + a2*dx^3 + a3*dx^4.
205 double p = poly_approx_d(dx);
206
207 double lo = fputil::multiply_add(p, mid_lo, exp_mid.lo);
208
209#ifdef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
210 return ziv_test_denorm</*SKIP_ZIV_TEST=*/true>(hi, exp_mid.hi, lo, ERR_D)
211 .value();
212#else
213 if (auto r = ziv_test_denorm(hi, exp_mid.hi, lo, ERR_D);
214 LIBC_LIKELY(r.has_value()))
215 return r.value();
216
217 // Use double-double
218 DoubleDouble r_dd = exp10_double_double(x, kd, exp_mid);
219
220 if (auto r = ziv_test_denorm(hi, r_dd.hi, r_dd.lo, ERR_DD);
221 LIBC_LIKELY(r.has_value()))
222 return r.value();
223
224 // Use 128-bit precision
225 Float128 r_f128 = exp10_f128(x, kd, idx1, idx2);
226
227 return static_cast<double>(r_f128);
228#endif // LIBC_MATH_HAS_SKIP_ACCURATE_PASS
229}
230
231// Check for exceptional cases when:
232// * log10(1 - 2^-54) < x < log10(1 + 2^-53)

Callers 1

set_exceptionalFunction · 0.85

Calls 6

multiply_addFunction · 0.85
exp10_double_doubleFunction · 0.85
exp10_f128Function · 0.85
poly_approx_dFunction · 0.70
valueMethod · 0.45
has_valueMethod · 0.45

Tested by

no test coverage detected