http://www.ganssle.com/item/approximations-c-code-exponentiation-log.htm
| 184 | |
| 185 | // http://www.ganssle.com/item/approximations-c-code-exponentiation-log.htm |
| 186 | inline vfloat spmd_kernel::exp2_est(vfloat arg) |
| 187 | { |
| 188 | SPMD_BEGIN_CALL |
| 189 | |
| 190 | const vfloat P00 = +7.2152891521493f; |
| 191 | const vfloat P01 = +0.0576900723731f; |
| 192 | const vfloat Q00 = +20.8189237930062f; |
| 193 | const vfloat Q01 = +1.0f; |
| 194 | const vfloat sqrt2 = 1.4142135623730950488f; // sqrt(2) for scaling |
| 195 | |
| 196 | vfloat result = 0.0f; |
| 197 | |
| 198 | // Return 0 if arg is too large. |
| 199 | // We're not introducing inf/nan's into calculations, or risk doing so by returning huge default values. |
| 200 | SPMD_IF(abs(arg) > 126.0f) |
| 201 | { |
| 202 | spmd_return(); |
| 203 | } |
| 204 | SPMD_END_IF |
| 205 | |
| 206 | // 2**(int(a)) |
| 207 | vfloat two_int_a; |
| 208 | |
| 209 | // set to 1 by reduce_expb |
| 210 | vint adjustment; |
| 211 | |
| 212 | // 0 if arg is +; 1 if negative |
| 213 | vint negative = 0; |
| 214 | |
| 215 | // If the input is negative, invert it. At the end we'll take the reciprocal, since n**(-1) = 1/(n**x). |
| 216 | SPMD_SIF(arg < 0.0f) |
| 217 | { |
| 218 | store(arg, -arg); |
| 219 | store(negative, 1); |
| 220 | } |
| 221 | SPMD_SENDIF |
| 222 | |
| 223 | store_all(arg, min(arg, 126.0f)); |
| 224 | |
| 225 | // reduce to [0.0, 0.5] |
| 226 | reduce_expb(arg, two_int_a, adjustment); |
| 227 | |
| 228 | // The format of the polynomial is: |
| 229 | // answer=(Q(x**2) + x*P(x**2))/(Q(x**2) - x*P(x**2)) |
| 230 | // |
| 231 | // The following computes the polynomial in several steps: |
| 232 | |
| 233 | // Q(x**2) |
| 234 | vfloat Q = vfma(Q01, (arg * arg), Q00); |
| 235 | |
| 236 | // x*P(x**2) |
| 237 | vfloat x_P = arg * (vfma(P01, arg * arg, P00)); |
| 238 | |
| 239 | vfloat answer = (Q + x_P) / (Q - x_P); |
| 240 | |
| 241 | // Now correct for the scaling factor of 2**(int(a)) |
| 242 | store_all(answer, answer * two_int_a); |
| 243 |
nothing calls this directly
no test coverage detected