| 10 | |
| 11 | namespace { |
| 12 | ASTPtr gen_powc(ASTPtr inp, float exp) { |
| 13 | auto int_neg = [exp](ASTPtr x) { |
| 14 | if (exp < 0) { |
| 15 | return 1.f / x; |
| 16 | } |
| 17 | return x; |
| 18 | }; |
| 19 | if (almost_equal(std::abs(exp), 0.f)) { |
| 20 | return 1.f; |
| 21 | } |
| 22 | if (almost_equal(std::abs(exp), 1.f)) { |
| 23 | return int_neg(inp); |
| 24 | } |
| 25 | if (almost_equal(std::abs(exp), 2.f)) { |
| 26 | return int_neg(inp * inp); |
| 27 | } |
| 28 | if (almost_equal(std::abs(exp), 3.f)) { |
| 29 | return int_neg(inp * inp * inp); |
| 30 | } |
| 31 | if (almost_equal(exp, 1.f / 3.f)) { |
| 32 | return make_call("cbrtf", {inp}); |
| 33 | } |
| 34 | if (almost_equal(exp, -1.f / 3.f)) { |
| 35 | return make_call("rcbrtf", {inp}); |
| 36 | } |
| 37 | if (almost_equal(exp, .5f)) { |
| 38 | return make_call("sqrtf", {inp}); |
| 39 | } |
| 40 | if (almost_equal(exp, -.5f)) { |
| 41 | return make_call("rsqrtf", {inp}); |
| 42 | } |
| 43 | int exp_i = std::round(exp); |
| 44 | if (almost_equal(static_cast<float>(exp_i), exp)) { |
| 45 | auto inp_abs = make_call("fabsf", {inp}); |
| 46 | if (exp_i & 1) { |
| 47 | auto pow = make_call("powf", {inp_abs, exp}); |
| 48 | return make_call("copysign", {pow, inp}); |
| 49 | } else { |
| 50 | return make_call("powf", {inp_abs, exp}); |
| 51 | } |
| 52 | } |
| 53 | |
| 54 | return make_call("powf", {inp, exp}); |
| 55 | } |
| 56 | |
| 57 | } // anonymous namespace |
| 58 |
no test coverage detected