From 95282f7d1a86e63cd773d5e45fc54769f6ee3c18 Mon Sep 17 00:00:00 2001 From: Robert Date: Sat, 18 Jul 2020 21:06:17 +0200 Subject: [PATCH 1/5] Added basic integer prototype --- .gitignore | 1 + CMakeLists.txt | 34 ++++++++++++++++---- include/gm3p.hpp | 4 +++ include/gm3p_int.hpp | 28 +++++++++++++++++ src/gm3p_int.cpp | 71 ++++++++++++++++++++++++++++++++++++++++++ testapp/CMakeLists.txt | 13 ++++++++ testapp/main.cpp | 17 ++++++++++ 7 files changed, 162 insertions(+), 6 deletions(-) create mode 100644 include/gm3p.hpp create mode 100644 include/gm3p_int.hpp create mode 100644 src/gm3p_int.cpp create mode 100644 testapp/CMakeLists.txt create mode 100644 testapp/main.cpp diff --git a/.gitignore b/.gitignore index 32dcdee..cf2580d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ .vs out +3rdparty *.json \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 33ce1c4..89d258b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,9 +1,31 @@ -# CMakeList.txt : Top-level CMake project file, do global configuration -# and include sub-projects here. -# -cmake_minimum_required (VERSION 3.8) +cmake_minimum_required (VERSION 3.8) -project ("GMP++") +project ("GM3p") + +set(GMP_INCLUDE_DIR "" CACHE PATH "Path to the directory containing 'gmp.h'") + +if(CMAKE_BUILD_TYPE EQUAL "DEBUG") + set(GMP_LIBRARY "" CACHE FILEPATH "Path to the gmp library") +else(CMAKE_BUILD_TYPE EQUAL "RELEASE") + set(GMP_LIBRARY "" CACHE FILEPATH "Path to the gmpDebug library") +endif() + +set(ENABLE_TEST_PROJ FALSE CACHE BOOL "Enable the testing project (usually not needed)") + +add_library(gm3p STATIC + "include/gm3p_int.hpp" "src/gm3p_int.cpp" +) + +target_include_directories(gm3p PUBLIC + include + ${GMP_INCLUDE_DIR} +) + +target_link_libraries(gm3p PUBLIC + ${GMP_LIBRARY} +) # Include sub-projects. -add_subdirectory ("GMP++") +if(ENABLE_TEST_PROJ) + add_subdirectory(testapp) +endif() \ No newline at end of file diff --git a/include/gm3p.hpp b/include/gm3p.hpp new file mode 100644 index 0000000..48fb703 --- /dev/null +++ b/include/gm3p.hpp @@ -0,0 +1,4 @@ +#pragma once +#include + +#include "gm3p_int.hpp" \ No newline at end of file diff --git a/include/gm3p_int.hpp b/include/gm3p_int.hpp new file mode 100644 index 0000000..d150fdc --- /dev/null +++ b/include/gm3p_int.hpp @@ -0,0 +1,28 @@ +#pragma once + +#include "gmp.h" + +namespace gm3p +{ + class gInt + { + public: + gInt(); + gInt(mpz_t init); + gInt(long int init); + gInt(const char* init, int base); + ~gInt(); + + gInt& operator=(const gInt& other); + + friend gInt operator+(const gInt& left, const gInt& right); + friend gInt operator-(const gInt& left, const gInt& right); + friend gInt operator*(const gInt& left, const gInt& right); + friend gInt operator/(const gInt& left, const gInt& right); + + friend std::ostream& operator<<(std::ostream& os, const gInt& value); + + private: + mpz_t value; + }; +} \ No newline at end of file diff --git a/src/gm3p_int.cpp b/src/gm3p_int.cpp new file mode 100644 index 0000000..e8daff3 --- /dev/null +++ b/src/gm3p_int.cpp @@ -0,0 +1,71 @@ +#include "gm3p.hpp" + +namespace gm3p +{ + gInt::gInt() + { + mpz_init(value); + } + + gInt::gInt(mpz_t init) + : gInt::gInt() + { + mpz_set(value, init); + } + + gInt::gInt(long int init) : + gInt::gInt() + { + mpz_set_si(value, init); + } + + gInt::gInt(const char* init, int base) : + gInt::gInt() + { + mpz_set_str(value, init, base); + } + + gInt::~gInt() + { + mpz_clear(value); + } + + gInt& gInt::operator=(const gInt& other) + { + mpz_set(this->value, other.value); + } + + gInt operator+(const gInt& left, const gInt& right) + { + gInt ret; + mpz_add(ret.value, left.value, right.value); + return ret; + } + + gInt operator-(const gInt& left, const gInt& right) + { + gInt ret; + mpz_sub(ret.value, left.value, right.value); + return ret; + } + + gInt operator*(const gInt& left, const gInt& right) + { + gInt ret; + mpz_mul(ret.value, left.value, right.value); + return ret; + } + + gInt operator/(const gInt& left, const gInt& right) + { + gInt ret; + mpz_div(ret.value, left.value, right.value); + return ret; + } + std::ostream& operator<<(std::ostream& os, const gInt& value) + { + static char* buf; + gmp_asprintf(&buf, "%Zd", value); + os << buf; + } +} \ No newline at end of file diff --git a/testapp/CMakeLists.txt b/testapp/CMakeLists.txt new file mode 100644 index 0000000..970d34c --- /dev/null +++ b/testapp/CMakeLists.txt @@ -0,0 +1,13 @@ +add_executable(testapp + "main.cpp" +) + +target_include_directories(testapp PUBLIC + ${GMP_INCLUDE_DIR} + ${CMAKE_SOURCE_DIR}/include +) + +target_link_libraries(testapp PUBLIC + ${GMP_LIBRARY} + gm3p +) \ No newline at end of file diff --git a/testapp/main.cpp b/testapp/main.cpp new file mode 100644 index 0000000..2f3cf9b --- /dev/null +++ b/testapp/main.cpp @@ -0,0 +1,17 @@ +#include "gm3p.hpp" + +#include + +using namespace gm3p; + +int main(int argc, char** argv) +{ + gInt a("12234234234095780349859034869034635235", 10); + gInt b("123534622305820985092875207398734234753", 10); + + gInt c = a * b; + + std::cout << a << " * " << b << " = " << c << std::endl; + + return 0; +} \ No newline at end of file From 97125eaf07ad1eb060eef6ad96a8d49bc6780ceb Mon Sep 17 00:00:00 2001 From: Robert Date: Sat, 18 Jul 2020 22:47:00 +0200 Subject: [PATCH 2/5] Added more operations and install statements --- .gitignore | 2 ++ CMakeLists.txt | 7 +++++-- include/gm3p.hpp | 1 - include/gm3p_int.hpp | 11 +++++++++++ src/gm3p_int.cpp | 39 +++++++++++++++++++++++++++++++++++++++ testapp/main.cpp | 2 +- 6 files changed, 58 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index cf2580d..aa8a0be 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,7 @@ .vs +.vscode out +build 3rdparty *.json \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 89d258b..70d2db3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required (VERSION 3.8) -project ("GM3p") +project ("gm3p" CXX) set(GMP_INCLUDE_DIR "" CACHE PATH "Path to the directory containing 'gmp.h'") @@ -28,4 +28,7 @@ target_link_libraries(gm3p PUBLIC # Include sub-projects. if(ENABLE_TEST_PROJ) add_subdirectory(testapp) -endif() \ No newline at end of file +endif() + +install(TARGETS gm3p DESTINATION lib) +install(DIRECTORY include DESTINATION .) \ No newline at end of file diff --git a/include/gm3p.hpp b/include/gm3p.hpp index 48fb703..629eb65 100644 --- a/include/gm3p.hpp +++ b/include/gm3p.hpp @@ -1,4 +1,3 @@ #pragma once -#include #include "gm3p_int.hpp" \ No newline at end of file diff --git a/include/gm3p_int.hpp b/include/gm3p_int.hpp index d150fdc..6d4e14f 100644 --- a/include/gm3p_int.hpp +++ b/include/gm3p_int.hpp @@ -1,5 +1,7 @@ #pragma once +#include + #include "gmp.h" namespace gm3p @@ -7,19 +9,28 @@ namespace gm3p class gInt { public: + // CONSTRUCTORS gInt(); gInt(mpz_t init); + gInt(unsigned long int init); gInt(long int init); gInt(const char* init, int base); ~gInt(); + // ASSIGNMENT OPERATORS gInt& operator=(const gInt& other); + // ARITHMETIC OPERATORS friend gInt operator+(const gInt& left, const gInt& right); friend gInt operator-(const gInt& left, const gInt& right); friend gInt operator*(const gInt& left, const gInt& right); friend gInt operator/(const gInt& left, const gInt& right); + gInt& operator+=(const gInt& right); + gInt& operator-=(const gInt& right); + gInt& operator*=(const gInt& right); + gInt& operator/=(const gInt& right); + friend std::ostream& operator<<(std::ostream& os, const gInt& value); private: diff --git a/src/gm3p_int.cpp b/src/gm3p_int.cpp index e8daff3..efd801a 100644 --- a/src/gm3p_int.cpp +++ b/src/gm3p_int.cpp @@ -13,6 +13,12 @@ namespace gm3p mpz_set(value, init); } + gInt::gInt(unsigned long int init) : + gInt::gInt() + { + mpz_set_ui(value, init); + } + gInt::gInt(long int init) : gInt::gInt() { @@ -30,11 +36,16 @@ namespace gm3p mpz_clear(value); } + + + gInt& gInt::operator=(const gInt& other) { mpz_set(this->value, other.value); } + + gInt operator+(const gInt& left, const gInt& right) { gInt ret; @@ -62,6 +73,34 @@ namespace gm3p mpz_div(ret.value, left.value, right.value); return ret; } + + + + gInt& gInt::operator+=(const gInt& right) + { + mpz_add(value, value, right.value); + return *this; + } + + gInt& gInt::operator-=(const gInt& right) + { + mpz_sub(value, value, right.value); + return *this; + } + + gInt& gInt::operator*=(const gInt& right) + { + mpz_mul(value, value, right.value); + return *this; + } + + gInt& gInt::operator/=(const gInt& right) + { + mpz_div(value, value, right.value); + return *this; + } + + std::ostream& operator<<(std::ostream& os, const gInt& value) { static char* buf; diff --git a/testapp/main.cpp b/testapp/main.cpp index 2f3cf9b..b41a5a9 100644 --- a/testapp/main.cpp +++ b/testapp/main.cpp @@ -1,6 +1,6 @@ #include "gm3p.hpp" -#include +//#include using namespace gm3p; From 971f13a59b347343b637aff1d85e8d297535d34c Mon Sep 17 00:00:00 2001 From: Robert Date: Sun, 19 Jul 2020 02:06:36 +0200 Subject: [PATCH 3/5] Finished operator overloading --- include/gm3p_int.hpp | 18 ++++++++++- src/gm3p_int.cpp | 72 +++++++++++++++++++++++++++++++++++++++----- testapp/main.cpp | 12 ++++++-- 3 files changed, 91 insertions(+), 11 deletions(-) diff --git a/include/gm3p_int.hpp b/include/gm3p_int.hpp index 6d4e14f..b72e611 100644 --- a/include/gm3p_int.hpp +++ b/include/gm3p_int.hpp @@ -12,13 +12,20 @@ namespace gm3p // CONSTRUCTORS gInt(); gInt(mpz_t init); + gInt(mpq_t init); + gInt(mpf_t init); gInt(unsigned long int init); gInt(long int init); gInt(const char* init, int base); + gInt(double init); + + // DESTRUCTOR ~gInt(); - // ASSIGNMENT OPERATORS + // ASSIGNMENT/COPY OPERATORS gInt& operator=(const gInt& other); + gInt(const gInt& other); + gInt(gInt&& other); // ARITHMETIC OPERATORS friend gInt operator+(const gInt& left, const gInt& right); @@ -31,6 +38,15 @@ namespace gm3p gInt& operator*=(const gInt& right); gInt& operator/=(const gInt& right); + // CONVERSION OPERATORS + operator long int() const; + + unsigned long int ToUnsigned() const; + char* ToString(char* buf, int base) const; + double ToDouble() const; + double ToDouble(long int* exp) const; + + // STDIO OPERATORS friend std::ostream& operator<<(std::ostream& os, const gInt& value); private: diff --git a/src/gm3p_int.cpp b/src/gm3p_int.cpp index efd801a..347cf0b 100644 --- a/src/gm3p_int.cpp +++ b/src/gm3p_int.cpp @@ -8,29 +8,46 @@ namespace gm3p } gInt::gInt(mpz_t init) - : gInt::gInt() { - mpz_set(value, init); + mpz_init_set(value, init); + } + + gInt::gInt(mpq_t init) + { + mpz_init(value); + mpz_set_q(value, init); + } + + gInt::gInt(mpf_t init) + { + mpz_init(value); + mpz_set_f(value, init); } gInt::gInt(unsigned long int init) : gInt::gInt() { - mpz_set_ui(value, init); + mpz_init_set_ui(value, init); } gInt::gInt(long int init) : gInt::gInt() { - mpz_set_si(value, init); + mpz_init_set_si(value, init); } gInt::gInt(const char* init, int base) : gInt::gInt() { - mpz_set_str(value, init, base); + mpz_init_set_str(value, init, base); } + gInt::gInt(double init) + { + mpz_init_set_d(value, init); + } + + gInt::~gInt() { mpz_clear(value); @@ -40,6 +57,17 @@ namespace gm3p gInt& gInt::operator=(const gInt& other) + { + mpz_set(this->value, other.value); + return *this; + } + + gInt::gInt(const gInt& other) + { + mpz_set(this->value, other.value); + } + + gInt::gInt(gInt&& other) { mpz_set(this->value, other.value); } @@ -100,11 +128,39 @@ namespace gm3p return *this; } + gInt::operator long int() const + { + return mpz_get_si(value); + } + + unsigned long int gInt::ToUnsigned() const + { + return mpz_get_ui(value); + } + + char* gInt::ToString(char* buf, int base) const + { + return mpz_get_str(buf, base, value); + } + + double gInt::ToDouble() const + { + return mpz_get_d(value); + } + + double gInt::ToDouble(long int* exp) const + { + return mpz_get_d_2exp(exp, value); + } + std::ostream& operator<<(std::ostream& os, const gInt& value) { - static char* buf; - gmp_asprintf(&buf, "%Zd", value); - os << buf; + os << value.ToString(NULL, + (os.flags() & std::ios_base::dec) != 0 ? 10 : + (os.flags() & std::ios_base::hex) != 0 ? 16 : + 8 + ); + return os; } } \ No newline at end of file diff --git a/testapp/main.cpp b/testapp/main.cpp index b41a5a9..d51f8ac 100644 --- a/testapp/main.cpp +++ b/testapp/main.cpp @@ -1,6 +1,7 @@ #include "gm3p.hpp" -//#include +#include +#include using namespace gm3p; @@ -9,9 +10,16 @@ int main(int argc, char** argv) gInt a("12234234234095780349859034869034635235", 10); gInt b("123534622305820985092875207398734234753", 10); + a *= b; gInt c = a * b; - std::cout << a << " * " << b << " = " << c << std::endl; + std::cout << std::dec << a << " * " << b << " = " << c << std::endl; + std::cout << std::hex << a << " * " << b << " = " << c << std::endl; + std::cout << std::oct << a << " * " << b << " = " << c << std::endl << std::endl << std::dec; + + int d = c; + std::cout << d << std::endl; + std::cout << c.ToString(NULL, 2) << std::endl; return 0; } \ No newline at end of file From 6d15af8b86e44b3465d89e7bb6af995211beb9ef Mon Sep 17 00:00:00 2001 From: Robert Date: Sun, 19 Jul 2020 17:01:23 +0200 Subject: [PATCH 4/5] Added more operations --- include/gm3p_int.hpp | 14 +++++++-- src/gm3p_int.cpp | 68 ++++++++++++++++++++++++++------------------ testapp/main.cpp | 12 ++++---- 3 files changed, 56 insertions(+), 38 deletions(-) diff --git a/include/gm3p_int.hpp b/include/gm3p_int.hpp index b72e611..f974cdf 100644 --- a/include/gm3p_int.hpp +++ b/include/gm3p_int.hpp @@ -6,6 +6,9 @@ namespace gm3p { + /** + * A wrapper for mpz_t + */ class gInt { public: @@ -14,10 +17,8 @@ namespace gm3p gInt(mpz_t init); gInt(mpq_t init); gInt(mpf_t init); - gInt(unsigned long int init); gInt(long int init); - gInt(const char* init, int base); - gInt(double init); + gInt(const char* init, int base = 10); // DESTRUCTOR ~gInt(); @@ -28,6 +29,8 @@ namespace gm3p gInt(gInt&& other); // ARITHMETIC OPERATORS + friend gInt operator-(const gInt& value); + friend gInt operator+(const gInt& left, const gInt& right); friend gInt operator-(const gInt& left, const gInt& right); friend gInt operator*(const gInt& left, const gInt& right); @@ -38,8 +41,13 @@ namespace gm3p gInt& operator*=(const gInt& right); gInt& operator/=(const gInt& right); + friend gInt Mul2Exp(const gInt& value, const mp_bitcnt_t& exp); + friend gInt Neg(const gInt& value); + friend gInt Abs(const gInt& value); + // CONVERSION OPERATORS operator long int() const; + operator mpz_t&(); unsigned long int ToUnsigned() const; char* ToString(char* buf, int base) const; diff --git a/src/gm3p_int.cpp b/src/gm3p_int.cpp index 347cf0b..91b528e 100644 --- a/src/gm3p_int.cpp +++ b/src/gm3p_int.cpp @@ -24,12 +24,6 @@ namespace gm3p mpz_set_f(value, init); } - gInt::gInt(unsigned long int init) : - gInt::gInt() - { - mpz_init_set_ui(value, init); - } - gInt::gInt(long int init) : gInt::gInt() { @@ -42,77 +36,69 @@ namespace gm3p mpz_init_set_str(value, init, base); } - gInt::gInt(double init) - { - mpz_init_set_d(value, init); - } - - gInt::~gInt() { mpz_clear(value); } - - - gInt& gInt::operator=(const gInt& other) { - mpz_set(this->value, other.value); + mpz_set(*this, const_cast(other)); return *this; } gInt::gInt(const gInt& other) { - mpz_set(this->value, other.value); + mpz_set(*this, const_cast(other)); } gInt::gInt(gInt&& other) { - mpz_set(this->value, other.value); + mpz_set(*this, const_cast(other)); } - + gInt operator-(const gInt& value) + { + return Neg(value); + } gInt operator+(const gInt& left, const gInt& right) { gInt ret; - mpz_add(ret.value, left.value, right.value); + mpz_add(ret, const_cast(left), const_cast(right)); return ret; } gInt operator-(const gInt& left, const gInt& right) { gInt ret; - mpz_sub(ret.value, left.value, right.value); + mpz_sub(ret, const_cast(left), const_cast(right)); return ret; } gInt operator*(const gInt& left, const gInt& right) { gInt ret; - mpz_mul(ret.value, left.value, right.value); + mpz_mul(ret, const_cast(left), const_cast(right)); return ret; } gInt operator/(const gInt& left, const gInt& right) { gInt ret; - mpz_div(ret.value, left.value, right.value); + mpz_div(ret, const_cast(left), const_cast(right)); return ret; } - - gInt& gInt::operator+=(const gInt& right) { - mpz_add(value, value, right.value); + mpz_add(value, value, const_cast(right)); return *this; } gInt& gInt::operator-=(const gInt& right) { - mpz_sub(value, value, right.value); + mpz_sub(value, value, const_cast(right)); return *this; } @@ -124,15 +110,41 @@ namespace gm3p gInt& gInt::operator/=(const gInt& right) { - mpz_div(value, value, right.value); + mpz_div(value, value, const_cast(right)); return *this; } + gInt Mul2Exp(const gInt& value, const mp_bitcnt_t& exp) + { + gInt ret; + mpz_mul_2exp(ret, const_cast(value), exp); + return ret; + } + + gInt Neg(const gInt& value) + { + gInt ret; + mpz_neg(ret, const_cast(value)); + return ret; + } + + gInt Abs(const gInt& value) + { + gInt ret; + mpz_abs(ret, const_cast(value)); + return ret; + } + gInt::operator long int() const { return mpz_get_si(value); } + gInt::operator mpz_t&() + { + return value; + } + unsigned long int gInt::ToUnsigned() const { return mpz_get_ui(value); diff --git a/testapp/main.cpp b/testapp/main.cpp index d51f8ac..071b693 100644 --- a/testapp/main.cpp +++ b/testapp/main.cpp @@ -7,17 +7,15 @@ using namespace gm3p; int main(int argc, char** argv) { - gInt a("12234234234095780349859034869034635235", 10); - gInt b("123534622305820985092875207398734234753", 10); + gInt a("12"); + gInt b = -5; - a *= b; gInt c = a * b; - std::cout << std::dec << a << " * " << b << " = " << c << std::endl; - std::cout << std::hex << a << " * " << b << " = " << c << std::endl; - std::cout << std::oct << a << " * " << b << " = " << c << std::endl << std::endl << std::dec; + std::cout << c << std::endl << std::endl; + std::cout << -c << std::endl << std::endl; - int d = c; + int d = Abs(c); std::cout << d << std::endl; std::cout << c.ToString(NULL, 2) << std::endl; From 551f93afbd52b302b47cd2e7dc7da686512b1127 Mon Sep 17 00:00:00 2001 From: Robert Date: Sun, 19 Jul 2020 20:20:06 +0200 Subject: [PATCH 5/5] Added mpz_t return to testapp --- testapp/main.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/testapp/main.cpp b/testapp/main.cpp index 071b693..409108d 100644 --- a/testapp/main.cpp +++ b/testapp/main.cpp @@ -17,7 +17,11 @@ int main(int argc, char** argv) int d = Abs(c); std::cout << d << std::endl; - std::cout << c.ToString(NULL, 2) << std::endl; + std::cout << c.ToString(NULL, 2) << std::endl << std::endl; + + mpz_t& e = c; + mpz_mul_ui(e, e, 2); + std::cout << c << std::endl; return 0; } \ No newline at end of file