diff --git a/docs/manual/functions.qmd b/docs/manual/functions.qmd
index 1fb40ba..35bb905 100644
--- a/docs/manual/functions.qmd
+++ b/docs/manual/functions.qmd
@@ -52,6 +52,8 @@ The following built-in functions are available:
| SIN(Number) | Sine of the angle *Number* in radians. |
| SINH(Number) | Hyperbolic sine of *Number*. |
| SQRT(Number) | Square root of *Number*. |
+| SUPPORTS32BIT() | Returns true if 32-bit integers are supported. This will affect the supported range of values for bitwise operations. |
+| SUPPORTS64BIT() | Returns true if 64-bit integers are supported. This will affect the supported range of values for bitwise operations. |
| TAN(Number) | Tangent of *Number*. |
| TGAMMA(Number) | Returns the gamma function of *Number*. |
| TRUNC(Number) | Discards the fractional part of *Number*.
\linebreak `TRUNC(-3.2)` = -3
\linebreak `TRUNC(3.2)` = 3 |
diff --git a/tests/tetests.cpp b/tests/tetests.cpp
index bd5b646..1416faa 100644
--- a/tests/tetests.cpp
+++ b/tests/tetests.cpp
@@ -758,6 +758,38 @@ TEST_CASE("Zeros", "[zeros]")
CHECK(std::isnan(tep.evaluate("(1%0)%1")));
}
+TEST_CASE("UINT support", "[uint]")
+ {
+ te_parser tep;
+
+ if constexpr(te_parser::supports_32bit())
+ {
+ INFO("Checking for handling of large value: " +
+ std::to_string(std::numeric_limits::max()));
+ CHECK(tep.evaluate(std::to_string(std::numeric_limits::max())) ==
+ std::numeric_limits::max());
+ CHECK(tep.evaluate(
+ "(" + std::to_string(std::numeric_limits::max()) + " - 100) + 100") ==
+ std::numeric_limits::max());
+ CHECK(tep.evaluate(
+ std::to_string(std::numeric_limits::max()) + " - 700") ==
+ std::numeric_limits::max() - 700);
+ }
+
+ if constexpr(te_parser::supports_64bit())
+ {
+ INFO("Checking for handling of large value: " +
+ std::to_string(std::numeric_limits::max()));
+ CHECK(tep.evaluate(std::to_string(std::numeric_limits::max())) ==
+ std::numeric_limits::max());
+ CHECK(tep.evaluate(
+ "(" + std::to_string(std::numeric_limits::max()) + " - 100) + 100") ==
+ std::numeric_limits::max());
+ CHECK(tep.evaluate(
+ std::to_string(std::numeric_limits::max()) + " - 700") ==
+ std::numeric_limits::max() - 700);
+ }
+ }
TEST_CASE("Braces", "[braces]")
{
diff --git a/tinyexpr.cpp b/tinyexpr.cpp
index b859571..7b370a8 100644
--- a/tinyexpr.cpp
+++ b/tinyexpr.cpp
@@ -848,6 +848,18 @@ namespace te_builtins
return te_parser::te_max_value;
}
+ [[nodiscard]]
+ constexpr static te_type te_supports_32bit() noexcept
+ {
+ return te_parser::supports_32bit() ? 1.0 : 0.0;
+ }
+
+ [[nodiscard]]
+ constexpr static te_type te_supports_64bit() noexcept
+ {
+ return te_parser::supports_64bit() ? 1.0 : 0.0;
+ }
+
// cotangent
[[nodiscard]]
static te_type te_cot(te_type val) noexcept
@@ -986,6 +998,8 @@ const std::set te_parser::m_functions = { // NOLINT
{ "sqrt", static_cast(te_builtins::te_sqrt), TE_PURE },
{ "sum", static_cast(te_builtins::te_sum),
static_cast(TE_PURE | TE_VARIADIC) },
+ { "supports32bit", static_cast(te_builtins::te_supports_32bit), TE_PURE },
+ { "supports64bit", static_cast(te_builtins::te_supports_64bit), TE_PURE },
{ "tan", static_cast(te_builtins::te_tan), TE_PURE },
{ "tanh", static_cast(te_builtins::te_tanh), TE_PURE },
{ "tgamma", static_cast(te_builtins::te_tgamma), TE_PURE },
diff --git a/tinyexpr.h b/tinyexpr.h
index 9380b4d..941f8b0 100644
--- a/tinyexpr.h
+++ b/tinyexpr.h
@@ -254,6 +254,16 @@ class te_parser
/// @brief No position, which is what get_last_error_position() returns
/// when there was no parsing error.
constexpr static int64_t npos = -1;
+ /// @returns @c true if the parser's internal type can hold `uint32_t` without truncation.
+ constexpr static bool supports_32bit() noexcept
+ {
+ return std::numeric_limits::digits >= std::numeric_limits::digits;
+ }
+ /// @returns @c true if the parser's internal type can hold `uint64_t` without truncation.
+ constexpr static bool supports_64bit() noexcept
+ {
+ return std::numeric_limits::digits >= std::numeric_limits::digits;
+ }
/** @brief Parses the input @c expression.
@param expression The formula to compile.
@returns Whether the expression compiled or not. (This can be checked