Skip to content

Commit

Permalink
Added two new compile flags, TE_RAND_SEED_TIME and TE_RAND_SEED
Browse files Browse the repository at this point in the history
TE_RAND_SEED_TIME uses time to see the mersenne twiser (ESP32 microcontrollers don't support entropy devices).
  • Loading branch information
Blake-Madden committed Dec 28, 2024
1 parent b72973c commit 9872e59
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 2 deletions.
12 changes: 12 additions & 0 deletions docs/manual/compile-time-options.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,18 @@ Compile with `TE_LONG_DOUBLE` defined to use `long double` as the default data t
Depending on the compiler, this may provide support for handling `uint64_t` values. Call `te_parser::supports_64bit()`
(or `SUPPORTS64BIT()` in an expression at runtime) to confirm this.

## `TE_RAND_SEED` {-}

Define this as an unsigned integer to seed the random number generator with.
This will affect the function `RAND()`, causing it to produce a deterministic series of numbers.

## `TE_RAND_SEED_TIME` {-}

Compile with `TE_RAND_SEED_TIME` to seed the random number generator with the current time.
This is useful if compiling for microcontrollers that do not support entropy devices.

The default is to seed the random number generator with `std::random_device`.

## `TE_BITWISE_OPERATORS` {-#te-bitwise-ops}

By default, the operators `&`, `|`, and `^` represent logical AND, logical OR, and exponentiation. If `TE_BITWISE_OPERATORS` is defined,
Expand Down
5 changes: 5 additions & 0 deletions docs/manual/embedded-programming.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ case insensitivity, and bookkeeping operations.

Refer to [compile-time options](#compile-time-options) for flags that can provide optimization.

## Device Compatibility

By default, *TinyExpr++* uses `std::random_device` to seed its random number generator, which may cause compatibility issues with some microcontrollers.
To instead seed it with the current time, compile with `TE_RAND_SEED_TIME`.

## Volatility {-}

If needing to use a `te_parser` object as `volatile`
Expand Down
5 changes: 4 additions & 1 deletion tests/tetests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2202,8 +2202,11 @@ TEST_CASE("Random", "[random]")
{
te_parser tep;
// can't have reproducible results for rand, so just run it and make
// sure it doesn't crash
// sure it doesn't crash...
CHECK_NOTHROW(tep.evaluate("rand()"));
// ...and within 0-1
auto res = tep.evaluate("rand()");
CHECK((res >= 0 && res <= 1));
}

TEST_CASE("Available functions", "[available]")
Expand Down
9 changes: 8 additions & 1 deletion tinyexpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -360,8 +360,15 @@ namespace te_builtins
[[nodiscard]]
static te_type te_random()
{
std::random_device rdev;
#ifdef TE_RAND_SEED
std::mt19937 gen(static_cast<unsigned int>(RAND_SEED));
#elif defined(TE_RAND_SEED_TIME)
std::mt19937 gen(static_cast<unsigned int>(time(nullptr)));
#else
static std::random_device rdev;
std::mt19937 gen(rdev());
#endif

std::uniform_real_distribution<te_type> distr(0, 1);
return distr(gen);
}
Expand Down
5 changes: 5 additions & 0 deletions tinyexpr.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <functional>
#include <initializer_list>
#include <limits>
Expand All @@ -76,6 +77,10 @@

class te_parser;

#if defined(TE_RAND_SEED) && defined(TE_RAND_SEED_TIME)
#error TE_RAND_SEED and TE_RAND_SEED_TIME compile options cannot be combined. Only one random number generator seeding method can be specified.
#endif

#if defined(TE_FLOAT) && defined(TE_LONG_DOUBLE)
#error TE_FLOAT and TE_LONG_DOUBLE compile options cannot be combined. Only one data type can be specified.
#endif
Expand Down

0 comments on commit 9872e59

Please sign in to comment.