From 33585cb36fb452e992e6031dcdda918f7c12cdd1 Mon Sep 17 00:00:00 2001 From: fallenoak Date: Sun, 29 Jan 2023 22:12:59 -0600 Subject: [PATCH] feat(big): add SBigAdd --- storm/Big.cpp | 4 +++ storm/Big.hpp | 2 ++ storm/big/Ops.cpp | 11 ++++++ storm/big/Ops.hpp | 2 ++ test/Big.cpp | 91 +++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 110 insertions(+) diff --git a/storm/Big.cpp b/storm/Big.cpp index 89a94be..5b28cfe 100644 --- a/storm/Big.cpp +++ b/storm/Big.cpp @@ -3,6 +3,10 @@ #include "storm/Memory.hpp" #include +void SBigAdd(BigData* a, BigData* b, BigData* c) { + Add(a->Primary(), b->Primary(), c->Primary()); +} + void SBigDel(BigData* num) { delete num; } diff --git a/storm/Big.hpp b/storm/Big.hpp index c1d42e5..a12566b 100644 --- a/storm/Big.hpp +++ b/storm/Big.hpp @@ -4,6 +4,8 @@ #include "storm/big/BigData.hpp" #include +void SBigAdd(BigData* a, BigData* b, BigData* c); + void SBigDel(BigData* num); void SBigFromBinary(BigData* num, const void* data, uint32_t bytes); diff --git a/storm/big/Ops.cpp b/storm/big/Ops.cpp index efd3db3..5a3a36f 100644 --- a/storm/big/Ops.cpp +++ b/storm/big/Ops.cpp @@ -1,5 +1,16 @@ #include "storm/big/Ops.hpp" +void Add(BigBuffer& a, const BigBuffer& b, const BigBuffer& c) { + uint64_t carry = 0; + uint32_t i = 0; + for (i = 0; carry || b.IsUsed(i) || c.IsUsed(i); i++) { + carry += static_cast(b[i]) + c[i]; + a[i] = ExtractLowPart(carry); + } + + a.SetCount(i); +} + uint32_t ExtractLowPart(uint64_t& value) { auto low = static_cast(value); value >>= 32; diff --git a/storm/big/Ops.hpp b/storm/big/Ops.hpp index 880a5df..6db197b 100644 --- a/storm/big/Ops.hpp +++ b/storm/big/Ops.hpp @@ -4,6 +4,8 @@ #include "storm/big/BigBuffer.hpp" #include +void Add(BigBuffer& a, const BigBuffer& b, const BigBuffer& c); + uint32_t ExtractLowPart(uint64_t& value); uint32_t ExtractLowPartSx(uint64_t& value); diff --git a/test/Big.cpp b/test/Big.cpp index 5897afc..637ea1c 100644 --- a/test/Big.cpp +++ b/test/Big.cpp @@ -68,6 +68,97 @@ TEST_CASE("MakeLarge", "[big]") { } } +TEST_CASE("SBigAdd", "[big]") { + SECTION("adds 0 and 1") { + BigData* a; + SBigNew(&a); + + BigData* b; + SBigNew(&b); + SBigFromUnsigned(b, 0); + + BigData* c; + SBigNew(&c); + SBigFromUnsigned(c, 1); + + SBigAdd(a, b, c); + + CHECK(a->Primary().Count() == 1); + CHECK(a->Primary()[0] == 1); + + SBigDel(a); + SBigDel(b); + SBigDel(c); + } + + SECTION("adds 1 and 2") { + BigData* a; + SBigNew(&a); + + BigData* b; + SBigNew(&b); + SBigFromUnsigned(b, 1); + + BigData* c; + SBigNew(&c); + SBigFromUnsigned(c, 2); + + SBigAdd(a, b, c); + + CHECK(a->Primary().Count() == 1); + CHECK(a->Primary()[0] == 3); + + SBigDel(a); + SBigDel(b); + SBigDel(c); + } + + SECTION("adds 0x12345678 and 0x23456789") { + BigData* a; + SBigNew(&a); + + BigData* b; + SBigNew(&b); + SBigFromUnsigned(b, 0x12345678); + + BigData* c; + SBigNew(&c); + SBigFromUnsigned(c, 0x23456789); + + SBigAdd(a, b, c); + + CHECK(a->Primary().Count() == 1); + CHECK(a->Primary()[0] == 0x3579BE01); + + SBigDel(a); + SBigDel(b); + SBigDel(c); + } + + SECTION("adds 0xFFFFFFFF and 0xF0F0F0F0") { + BigData* a; + SBigNew(&a); + + BigData* b; + SBigNew(&b); + SBigFromUnsigned(b, 0xFFFFFFFF); + + BigData* c; + SBigNew(&c); + SBigFromUnsigned(c, 0xF0F0F0F0); + + SBigAdd(a, b, c); + + CHECK(a->Primary().Count() == 2); + CHECK(a->Primary()[0] == 0xF0F0F0EF); + CHECK(a->Primary()[1] == 0x1); + + SBigDel(a); + SBigDel(b); + SBigDel(c); + } +} + TEST_CASE("SBigFromBinary", "[big]") { SECTION("creates bigdata from 0") { BigData* num;