diff --git a/storm/CMakeLists.txt b/storm/CMakeLists.txt index 92ef8c9..c204bee 100644 --- a/storm/CMakeLists.txt +++ b/storm/CMakeLists.txt @@ -3,6 +3,7 @@ check_cxx_compiler_flag(-Wno-invalid-offsetof HAS_NO_INVALID_OFFSETOF) file(GLOB STORM_SOURCES "*.cpp" + "big/*.cpp" "hash/*.cpp" "queue/*.cpp" "string/*.cpp" diff --git a/storm/big/Ops.cpp b/storm/big/Ops.cpp new file mode 100644 index 0000000..d2200d4 --- /dev/null +++ b/storm/big/Ops.cpp @@ -0,0 +1,24 @@ +#include "storm/big/Ops.hpp" + +uint32_t ExtractLowPart(uint64_t& value) { + auto low = static_cast(value); + value >>= 32; + + return low; +} + +uint32_t ExtractLowPartSx(uint64_t& value) { + auto low = static_cast(value); + value >>= 32; + + if (value >= 0x80000000) { + reinterpret_cast(&value)[0] = value; + reinterpret_cast(&value)[1] = -1; + } + + return low; +} + +uint64_t MakeLarge(uint32_t low, uint32_t high) { + return low + (static_cast(high) << 32); +} diff --git a/storm/big/Ops.hpp b/storm/big/Ops.hpp new file mode 100644 index 0000000..fb0b9e5 --- /dev/null +++ b/storm/big/Ops.hpp @@ -0,0 +1,12 @@ +#ifndef STORM_BIG_OPS_HPP +#define STORM_BIG_OPS_HPP + +#include + +uint32_t ExtractLowPart(uint64_t& value); + +uint32_t ExtractLowPartSx(uint64_t& value); + +uint64_t MakeLarge(uint32_t low, uint32_t high); + +#endif diff --git a/test/Big.cpp b/test/Big.cpp new file mode 100644 index 0000000..702a5d9 --- /dev/null +++ b/test/Big.cpp @@ -0,0 +1,68 @@ +#include "storm/big/Ops.hpp" +#include "test/Test.hpp" + +TEST_CASE("ExtractLowPart", "[big]") { + SECTION("extracts low part of 0") { + uint64_t value = 0; + auto low = ExtractLowPart(value); + + REQUIRE(low == 0); + REQUIRE(value == 0); + } + + SECTION("extracts low part of 0x12345678") { + uint64_t value = 0x12345678; + auto low = ExtractLowPart(value); + + REQUIRE(low == 0x12345678); + REQUIRE(value == 0); + } + + SECTION("extracts low part of 0xAAAABBBBCCCCDDDD") { + uint64_t value = 0xAAAABBBBCCCCDDDD; + auto low = ExtractLowPart(value); + + REQUIRE(low == 0xCCCCDDDD); + REQUIRE(value == 0xAAAABBBB); + } +} + +TEST_CASE("ExtractLowPartSx", "[big]") { + SECTION("extracts low part of 0") { + uint64_t value = 0; + auto low = ExtractLowPartSx(value); + + REQUIRE(low == 0); + REQUIRE(value == 0); + } + + SECTION("extracts low part of 0x12345678") { + uint64_t value = 0x12345678; + auto low = ExtractLowPartSx(value); + + REQUIRE(low == 0x12345678); + REQUIRE(value == 0); + } + + SECTION("extracts low part of 0xAAAABBBBCCCCDDDD") { + uint64_t value = 0xAAAABBBBCCCCDDDD; + auto low = ExtractLowPartSx(value); + + REQUIRE(low == 0xCCCCDDDD); + REQUIRE(value == 0xFFFFFFFFAAAABBBB); + } +} + +TEST_CASE("MakeLarge", "[big]") { + SECTION("creates uint64_t out of 0xAABBCCDD and 0x11223344") { + uint64_t value = MakeLarge(0xAABBCCDD, 0x11223344); + + REQUIRE(value == 0x11223344AABBCCDD); + } + + SECTION("creates uint64_t out of 0 and 0x11223344") { + uint64_t value = MakeLarge(0x00000000, 0x11223344); + + REQUIRE(value == 0x1122334400000000); + } +}