Loading impl/IntegerPP.cpp 0 → 100644 +106 −0 Original line number Diff line number Diff line // // Created by Ari on 1/31/26. // #include "../include/IntegerPP.h" bool isDivisible(const BigNum& num, const BigNum& divisor) { return divisor*(num/divisor)==num; } bool isPrimePlus(const BigNum& n) { if (n <= 1) return false; for (BigNum i = 2; i * i <= n; i=i+1) { if (isDivisible(n,i)) { return false; } } return true; } /** * @return The i-th prime, starting with i-thPrime(0)==2. */ BigNum ithPrimePlus(const size_t ii) { static auto memoized = vector<BigNum>(); if (memoized.size()>ii) // i.e., already memoized return memoized[ii]; BigNum prime=2; size_t ii_search=ii; while (ii_search!=0) { prime = prime + 1; if (isPrimePlus(prime)) ii_search--; } memoized.resize(ii+1); memoized[ii]=prime; return prime; } /** * Computes a positive integer power of an integer, using square-and-multiply. * @param base The base. * @param exp The exponent * @return base ^ exp * @requires exp>=0 * @thanks ChatGPT */ BigNum ipowPlus(BigNum base, int exp) { BigNum result = 1; while (exp > 0) { if (exp & 1) result *= base; base *= base; exp >>= 1; } return result; } // return true iff num1 > num2 bool BigNumGreater(const BigNum& num1, const BigNum& num2) { return (num2<=num1) && (!(num1==num2)); } IntegerPP::IntegerPP(BigNum num) { int ii=-1; while (BigNumGreater(num,1)) { ii++; if (isDivisible(num, ithPrimePlus(ii))) { if (_primePowers.size()<=static_cast<size_t>(ii) ) // make sure that space is allocated _primePowers.resize(ii+1); _primePowers[ii]++; num/=ithPrimePlus(ii); ii--; } } } IntegerPP::operator BigNum() const { BigNum result=1; for (size_t ii=0; ii<_primePowers.size(); ii++) { result*=ipowPlus(ithPrimePlus(ii),_primePowers[ii]); } return result; } IntegerPP IntegerPP::operator+(const IntegerPP &addor) const { return IntegerPP(static_cast<BigNum>(*this) + static_cast<BigNum>(addor)); } IntegerPP & IntegerPP::operator=(const IntegerPP &rhs) { if (this !=& rhs) { _primePowers=rhs._primePowers; } return *this; } IntegerPP::IntegerPP() = default; IntegerPP::IntegerPP(unsigned long n):IntegerP(n) {} IntegerPP::IntegerPP(std::initializer_list<int> pBasis):IntegerP(pBasis) {} IntegerPP::IntegerPP(const IntegerP& other):IntegerP(other) {} No newline at end of file Loading
impl/IntegerPP.cpp 0 → 100644 +106 −0 Original line number Diff line number Diff line // // Created by Ari on 1/31/26. // #include "../include/IntegerPP.h" bool isDivisible(const BigNum& num, const BigNum& divisor) { return divisor*(num/divisor)==num; } bool isPrimePlus(const BigNum& n) { if (n <= 1) return false; for (BigNum i = 2; i * i <= n; i=i+1) { if (isDivisible(n,i)) { return false; } } return true; } /** * @return The i-th prime, starting with i-thPrime(0)==2. */ BigNum ithPrimePlus(const size_t ii) { static auto memoized = vector<BigNum>(); if (memoized.size()>ii) // i.e., already memoized return memoized[ii]; BigNum prime=2; size_t ii_search=ii; while (ii_search!=0) { prime = prime + 1; if (isPrimePlus(prime)) ii_search--; } memoized.resize(ii+1); memoized[ii]=prime; return prime; } /** * Computes a positive integer power of an integer, using square-and-multiply. * @param base The base. * @param exp The exponent * @return base ^ exp * @requires exp>=0 * @thanks ChatGPT */ BigNum ipowPlus(BigNum base, int exp) { BigNum result = 1; while (exp > 0) { if (exp & 1) result *= base; base *= base; exp >>= 1; } return result; } // return true iff num1 > num2 bool BigNumGreater(const BigNum& num1, const BigNum& num2) { return (num2<=num1) && (!(num1==num2)); } IntegerPP::IntegerPP(BigNum num) { int ii=-1; while (BigNumGreater(num,1)) { ii++; if (isDivisible(num, ithPrimePlus(ii))) { if (_primePowers.size()<=static_cast<size_t>(ii) ) // make sure that space is allocated _primePowers.resize(ii+1); _primePowers[ii]++; num/=ithPrimePlus(ii); ii--; } } } IntegerPP::operator BigNum() const { BigNum result=1; for (size_t ii=0; ii<_primePowers.size(); ii++) { result*=ipowPlus(ithPrimePlus(ii),_primePowers[ii]); } return result; } IntegerPP IntegerPP::operator+(const IntegerPP &addor) const { return IntegerPP(static_cast<BigNum>(*this) + static_cast<BigNum>(addor)); } IntegerPP & IntegerPP::operator=(const IntegerPP &rhs) { if (this !=& rhs) { _primePowers=rhs._primePowers; } return *this; } IntegerPP::IntegerPP() = default; IntegerPP::IntegerPP(unsigned long n):IntegerP(n) {} IntegerPP::IntegerPP(std::initializer_list<int> pBasis):IntegerP(pBasis) {} IntegerPP::IntegerPP(const IntegerP& other):IntegerP(other) {} No newline at end of file