From f01c906aa12f7b902a2322216b7302f2c4ca6415 Mon Sep 17 00:00:00 2001 From: fallenoak Date: Fri, 3 Feb 2023 00:43:20 -0600 Subject: [PATCH] feat(big): add ExtractLowPartLargeSum --- storm/big/Ops.cpp | 8 ++++++++ storm/big/Ops.hpp | 2 ++ test/Big.cpp | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 57 insertions(+) diff --git a/storm/big/Ops.cpp b/storm/big/Ops.cpp index 3e094bc..2affe61 100644 --- a/storm/big/Ops.cpp +++ b/storm/big/Ops.cpp @@ -58,6 +58,14 @@ uint32_t ExtractLowPart(uint64_t& value) { return low; } +uint32_t ExtractLowPartLargeSum(uint64_t& value, uint64_t add) { + auto carry = (value += add) < add; + auto low = ExtractLowPart(value); + value += static_cast(carry) << 32; + + return low; +} + uint32_t ExtractLowPartSx(uint64_t& value) { auto low = static_cast(value); value >>= 32; diff --git a/storm/big/Ops.hpp b/storm/big/Ops.hpp index 99fc457..94b502b 100644 --- a/storm/big/Ops.hpp +++ b/storm/big/Ops.hpp @@ -15,6 +15,8 @@ void Div(BigBuffer& a, uint32_t* b, const BigBuffer& c, uint64_t d); uint32_t ExtractLowPart(uint64_t& value); +uint32_t ExtractLowPartLargeSum(uint64_t& value, uint64_t add); + uint32_t ExtractLowPartSx(uint64_t& value); void FromBinary(BigBuffer& buffer, const void* value, uint32_t bytes); diff --git a/test/Big.cpp b/test/Big.cpp index c1ba4dd..e22c214 100644 --- a/test/Big.cpp +++ b/test/Big.cpp @@ -288,6 +288,53 @@ TEST_CASE("ExtractLowPart", "[big]") { } } +TEST_CASE("ExtractLowPartLargeSum", "[big]") { + SECTION("extracts low part after adding 2 and 4") { + uint64_t value = 2; + uint64_t add = 4; + auto low = ExtractLowPartLargeSum(value, add); + + CHECK(low == 6); + CHECK(value == 0); + } + + SECTION("extracts low part after adding 0x1111111122222222 and 0x3333333344444444") { + uint64_t value = 0x1111111122222222; + uint64_t add = 0x3333333344444444; + auto low = ExtractLowPartLargeSum(value, add); + + CHECK(low == 0x66666666); + CHECK(value == 0x44444444); + } + + SECTION("extracts low part after adding 0xCCCCCCCCCCCCCCCC and 0x5555555555555555") { + uint64_t value = 0xCCCCCCCCCCCCCCCC; + uint64_t add = 0x5555555555555555; + auto low = ExtractLowPartLargeSum(value, add); + + CHECK(low == 0x22222221); + CHECK(value == 0x122222222); + } + + SECTION("extracts low part after adding 0xFFFFFFFFFFFFFFFF and 0") { + uint64_t value = 0xFFFFFFFFFFFFFFFF; + uint64_t add = 0; + auto low = ExtractLowPartLargeSum(value, add); + + CHECK(low == 0xFFFFFFFF); + CHECK(value == 0xFFFFFFFF); + } + + SECTION("extracts low part after adding 0xFFFFFFFFFFFFFFFF and 0xFFFFFFFFFFFFFFFF") { + uint64_t value = 0xFFFFFFFFFFFFFFFF; + uint64_t add = 0xFFFFFFFFFFFFFFFF; + auto low = ExtractLowPartLargeSum(value, add); + + CHECK(low == 0xFFFFFFFE); + CHECK(value == 0x1FFFFFFFF); + } +} + TEST_CASE("ExtractLowPartSx", "[big]") { SECTION("extracts low part of 0") { uint64_t value = 0;