When output is denormal.
| 181 | |
| 182 | // When output is denormal. |
| 183 | double 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) |
no test coverage detected