Preserve fractional exponents in the power operator (#353)

This commit is contained in:
fhgffy
2026-10-05 08:08:48 +02:00
committed by GitHub
parent 02f86731a3
commit 482473a878
3 changed files with 20 additions and 4 deletions
+2 -2
View File
@@ -311,11 +311,11 @@ class Renderer : public NodeVisitor {
} break;
case Op::Power: {
const auto args = get_arguments<2>(node);
if (args[0]->is_number_integer() && args[1]->get<const json::number_integer_t>() >= 0) {
if (args[0]->is_number_integer() && args[1]->is_number_integer() && args[1]->get<const json::number_integer_t>() >= 0) {
const auto result = static_cast<json::number_integer_t>(std::pow(args[0]->get<const json::number_integer_t>(), args[1]->get<const json::number_integer_t>()));
make_result(result);
} else {
const auto result = std::pow(args[0]->get<const json::number_float_t>(), args[1]->get<const json::number_integer_t>());
const auto result = std::pow(args[0]->get<const json::number_float_t>(), args[1]->get<const json::number_float_t>());
make_result(result);
}
} break;
+2 -2
View File
@@ -2472,11 +2472,11 @@ class Renderer : public NodeVisitor {
} break;
case Op::Power: {
const auto args = get_arguments<2>(node);
if (args[0]->is_number_integer() && args[1]->get<const json::number_integer_t>() >= 0) {
if (args[0]->is_number_integer() && args[1]->is_number_integer() && args[1]->get<const json::number_integer_t>() >= 0) {
const auto result = static_cast<json::number_integer_t>(std::pow(args[0]->get<const json::number_integer_t>(), args[1]->get<const json::number_integer_t>()));
make_result(result);
} else {
const auto result = std::pow(args[0]->get<const json::number_float_t>(), args[1]->get<const json::number_integer_t>());
const auto result = std::pow(args[0]->get<const json::number_float_t>(), args[1]->get<const json::number_float_t>());
make_result(result);
}
} break;
+16
View File
@@ -39,6 +39,22 @@ TEST_CASE("functions") {
CHECK(env.render("{{ 5 % 2 }}", data) == "1");
CHECK(env.render("{{ 7 % -2 }}", data) == "1");
CHECK(env.render("{{ 5^3 }}", data) == "125");
CHECK(env.render("{{ 9 ^ 0.5 }}", data) == "3.0");
CHECK(env.render("{{ 9.0 ^ 0.5 }}", data) == "3.0");
CHECK(env.render("{{ 4 ^ 1.5 }}", data) == "8.0");
CHECK(env.render("{{ 4.0 ^ 1.5 }}", data) == "8.0");
CHECK(env.render("{{ 4 ^ -0.5 }}", data) == "0.5");
CHECK(env.render("{{ 4.0 ^ -0.5 }}", data) == "0.5");
CHECK(env.render("{{ 4 ^ -1 }}", data) == "0.25");
CHECK(env.render("{{ 4.0 ^ 2 }}", data) == "16.0");
CHECK(env.render("{{ 4 ^ 2.0 }}", data) == "16.0");
CHECK(env.render("{{ 4 ^ 0 }}", data) == "1");
CHECK(env.render("{{ 4 ^ 0.0 }}", data) == "1.0");
CHECK(env.render("{{ -2 ^ 3 }}", data) == "-8");
data["base"] = 16;
data["exponent"] = 0.5;
CHECK(env.render("{{ base ^ exponent }}", data) == "4.0");
CHECK(env.render("{{ (base ^ exponent) + 2 }}", data) == "6.0");
CHECK(env.render("{{ 5 + 12 + 4 * (4 - (1 + 1))^2 - 75 * 1 }}", data) == "-42");
CHECK_THROWS_WITH(env.render("{{ +1 }}", data), "[inja.exception.parser_error] (at 1:7) too few arguments");