From 8d721ccaaa8d19044f97c419da5f7c68dc35805b Mon Sep 17 00:00:00 2001 From: Erki Date: Fri, 30 Apr 2021 18:31:24 +0300 Subject: [PATCH] Add Utility/Rand module --- Tests/CMakeLists.txt | 3 +- Tests/rand.cpp | 62 ++++++++++++++++++++++++++++++++++++ Utility/CMakeLists.txt | 1 + Utility/Inc/utility_rand.hpp | 40 +++++++++++++++++++++++ Utility/Src/utility_rand.cpp | 27 ++++++++++++++++ 5 files changed, 132 insertions(+), 1 deletion(-) create mode 100644 Tests/rand.cpp create mode 100644 Utility/Inc/utility_rand.hpp create mode 100644 Utility/Src/utility_rand.cpp diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index 1a472f1..7a2c9f2 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -14,7 +14,8 @@ add_executable(tests ringbuffer.cpp packet.cpp parser.cpp - button.cpp) + button.cpp + rand.cpp) target_link_libraries(tests PUBLIC diff --git a/Tests/rand.cpp b/Tests/rand.cpp new file mode 100644 index 0000000..b73bd1d --- /dev/null +++ b/Tests/rand.cpp @@ -0,0 +1,62 @@ +// +// Created by erki on 29.04.21. +// + +#include + +#include "utility_rand.hpp" + +TEST_CASE("rand32 is deterministic.", "[utility],[rand]") +{ + const std::uint32_t original_state = 34; + std::uint32_t state = original_state; + std::vector generated; + + for (int i = 0; i < 10; i++) + { + generated.push_back(Peripherals::rand32(state)); + } + + std::uint32_t new_state = original_state; + for (int i = 0; i < 10; i++) + { + REQUIRE(generated[i] == Peripherals::rand32(new_state)); + } +} + +TEST_CASE("rand64 is deterministic.", "[utility],[rand]") +{ + const std::uint64_t original_state = 10e4; + std::uint64_t state = original_state; + std::vector generated; + + for (int i = 0; i < 10; i++) + { + generated.push_back(Peripherals::rand64(state)); + } + + std::uint64_t new_state = original_state; + for (int i = 0; i < 10; i++) + { + REQUIRE(generated[i] == Peripherals::rand64(new_state)); + } +} + +TEST_CASE("rand and srand are deterministic", "[utility],[rand]") +{ + const std::uint32_t original_state = 34; + + Peripherals::srand(original_state); + std::vector generated; + + for (int i = 0; i < 10; i++) + { + generated.push_back(Peripherals::rand()); + } + + Peripherals::srand(original_state); + for (int i = 0; i < 10; i++) + { + REQUIRE(generated[i] == Peripherals::rand()); + } +} diff --git a/Utility/CMakeLists.txt b/Utility/CMakeLists.txt index 0ff13a7..34b11ff 100644 --- a/Utility/CMakeLists.txt +++ b/Utility/CMakeLists.txt @@ -7,6 +7,7 @@ cmake_minimum_required(VERSION 3.8 FATAL_ERROR) add_library(utility STATIC Src/utility_logging.cpp + Src/utility_rand.cpp ${additional_sources} ) diff --git a/Utility/Inc/utility_rand.hpp b/Utility/Inc/utility_rand.hpp new file mode 100644 index 0000000..4ed0c9a --- /dev/null +++ b/Utility/Inc/utility_rand.hpp @@ -0,0 +1,40 @@ +// +// Created by erki on 29.04.21. +// + +#ifndef SKULLC_UTILITY_RAND_HPP +#define SKULLC_UTILITY_RAND_HPP + +#include + +namespace Peripherals +{ + +inline std::uint32_t rand32(std::uint32_t& state) +{ + std::uint32_t x = state; + x ^= x << 13; + x ^= x >> 17; + x ^= x << 5; + state = x; + + return state; +} + +inline std::uint64_t rand64(std::uint64_t& state) +{ + std::uint64_t x = state; + x ^= x << 13; + x ^= x >> 7; + x ^= x << 17; + state = x; + + return state; +} + +void srand(const std::uint32_t& seed); +std::uint32_t rand(); + +} + +#endif //SKULLC_UTILITY_RAND_HPP diff --git a/Utility/Src/utility_rand.cpp b/Utility/Src/utility_rand.cpp new file mode 100644 index 0000000..2de4713 --- /dev/null +++ b/Utility/Src/utility_rand.cpp @@ -0,0 +1,27 @@ +// +// Created by erki on 29.04.21. +// + +#include "utility_rand.hpp" + +namespace +{ + +std::uint32_t rand_state = 0; + +} + +namespace Peripherals +{ + +void srand(const std::uint32_t& seed) +{ + rand_state = seed; +} + +std::uint32_t rand() +{ + return rand32(rand_state); +} + +}