From 6759cb4d7cceecce0e4b717a359808f0bf8ecf5c Mon Sep 17 00:00:00 2001 From: Adam Heinermann Date: Fri, 15 Nov 2024 08:27:03 -0800 Subject: [PATCH] feat(big) add SBigIsEven --- storm/Big.cpp | 4 ++++ storm/Big.hpp | 2 ++ storm/big/Ops.cpp | 4 ++++ storm/big/Ops.hpp | 2 ++ test/Big.cpp | 22 ++++++++++++++++++++++ 5 files changed, 34 insertions(+) diff --git a/storm/Big.cpp b/storm/Big.cpp index c04e91a..7e59fd3 100644 --- a/storm/Big.cpp +++ b/storm/Big.cpp @@ -69,6 +69,10 @@ void SBigInc(BigData* a, BigData* b) { Add(a->Primary(), b->Primary(), 1); } +int32_t SBigIsEven(BigData* a) { + return IsEven(a->Primary()); +} + void SBigMod(BigData* a, BigData* b, BigData* c) { uint32_t allocCount = 0; auto& scratch = a->Stack().Alloc(&allocCount); diff --git a/storm/Big.hpp b/storm/Big.hpp index bd7dac7..1f77ad7 100644 --- a/storm/Big.hpp +++ b/storm/Big.hpp @@ -28,6 +28,8 @@ void SBigFromUnsigned(BigData* num, uint32_t val); void SBigInc(BigData* a, BigData* b); +int32_t SBigIsEven(BigData* a); + void SBigMod(BigData* a, BigData* b, BigData* c); void SBigMul(BigData* a, BigData* b, BigData* c); diff --git a/storm/big/Ops.cpp b/storm/big/Ops.cpp index 4b2cdea..6d25914 100644 --- a/storm/big/Ops.cpp +++ b/storm/big/Ops.cpp @@ -211,6 +211,10 @@ void InsertLowPart(uint64_t& value, uint32_t low) { value = (value << 32) | low; } +int32_t IsEven(const BigBuffer &num) { + return num.Count() == 0 || (num[0] & 1) == 0; +} + 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 index 7a84657..2154dfc 100644 --- a/storm/big/Ops.hpp +++ b/storm/big/Ops.hpp @@ -33,6 +33,8 @@ uint32_t HighBitPos(const BigBuffer& buffer); void InsertLowPart(uint64_t& value, uint32_t low); +int32_t IsEven(const BigBuffer &num); + uint64_t MakeLarge(uint32_t low, uint32_t high); void Mul(BigBuffer& a, const BigBuffer& b, uint64_t c); diff --git a/test/Big.cpp b/test/Big.cpp index d6f93bf..6eae76c 100644 --- a/test/Big.cpp +++ b/test/Big.cpp @@ -426,6 +426,28 @@ TEST_CASE("SBigInc", "[big]") { } } +TEST_CASE("SBigIsEven", "[big]") { + BigDataTest a; + + SECTION("unset zero is even") { + CHECK(SBigIsEven(a)); + } + + SECTION("numbers are even") { + auto v = GENERATE(0ULL, 2ULL, 10ULL, 10000ULL, 0xFFFFFFFEULL, 0x9999888877776666ULL); + + SBigFromStr(a, std::to_string(v).c_str()); + CHECK(SBigIsEven(a)); + } + + SECTION("numbers are not even") { + auto v = GENERATE(1ULL, 3ULL, 37ULL, 999999999ULL, 0xFFFFFFFFFULL, 0x9999888877776667ULL); + + SBigFromStr(a, std::to_string(v).c_str()); + CHECK_FALSE(SBigIsEven(a)); + } +} + TEST_CASE("SBigMod", "[big]") { SECTION("mods 7 by 4") { BigData* a;