Commit 013efb7d authored by Ari Trachtenberg's avatar Ari Trachtenberg
Browse files

Initial commit

parent 524a12fc
Loading
Loading
Loading
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