Loading integerP.cpp 0 → 100644 +313 −0 Original line number Diff line number Diff line #ifndef INITEGERP_H #define INITEGERP_H #include <vector> #include <string> class IntegerP { public: IntegerP() { } IntegerP(unsigned long lnum) { if (lnum == 0) { lnum = 1; } unsigned long n = lnum; unsigned long prime = 2; while (n > 1) { int power = 0; // exponent of current prime at, count how many times it divides while (n % prime == 0) { n = n / prime; power += 1; } _primePowers.push_back(power); // next prime if (prime == 2) { prime = 3; } else { prime = prime + 2;//odd nums while (!isPrime(prime)) { prime = prime + 2;//skip non pimes } } } } IntegerP(const std::vector<int> &pBasis) { _primePowers = pBasis; } static IntegerP valueOf(const unsigned long lnum) { return IntegerP(lnum); } static IntegerP valueOf(const std::vector<int> &pBasis) { return IntegerP(pBasis); } IntegerP operator*(const IntegerP &multiplicand) const //multiplies two numbers { IntegerP result; unsigned long len1 = (unsigned long)_primePowers.size(); unsigned long len2 = (unsigned long)multiplicand._primePowers.size(); unsigned long maxLen = (len1 > len2 ? len1 : len2); result._primePowers.resize(maxLen); //result exponents unsigned long i = 0; while (i < maxLen) { int p1 = (i < len1 ? _primePowers[i] : 0); int p2 = (i < len2 ? multiplicand._primePowers[i] : 0); result._primePowers[i] = p1 + p2; i = i + 1; } return result; } IntegerP operator/(const IntegerP &divisor) const { IntegerP result; unsigned long len1 = (unsigned long)_primePowers.size(); unsigned long len2 = (unsigned long)divisor._primePowers.size(); unsigned long maxLen = (len1 > len2 ? len1 : len2); result._primePowers.resize(maxLen); unsigned long i = 0; while (i < maxLen) { int p1 = (i < len1 ? _primePowers[i] : 0); int p2 = (i < len2 ? divisor._primePowers[i] : 0); result._primePowers[i] = p1 - p2; i = i + 1; } return result; } bool operator==(const IntegerP &other) const { IntegerP a = *this; IntegerP b = other; a.trimZeros(); b.trimZeros(); //trim on copies if (a._primePowers.size() != b._primePowers.size()) { return false; } unsigned long len = (unsigned long)a._primePowers.size(); unsigned long i = 0; while (i < len) { if (a._primePowers[i] != b._primePowers[i]) { return false; } i = i + 1; } return true; } long trunc() const { long value = 1;//running product long maxVal = 9223372036854775807L;// max for 64 bit unsigned long prime = 2; // start at 2 and go through all primes used unsigned long i = 0; while (i < (unsigned long)_primePowers.size()) { int power = _primePowers[i]; int k = 0; while (k < power) { if (value != 0 && prime != 0) // if it goes past maxval { long limit = maxVal / (long)prime; if (value > limit) { return maxVal; } } value = value * (long)prime; k = k + 1; } if (prime == 2) //next prime { prime = 3; } else { prime = prime + 2; while (!isPrime(prime)) { prime = prime + 2; } } i = i + 1; } return value; } bool divisibleBy(const IntegerP &divisor) const { unsigned long len1 = (unsigned long)_primePowers.size(); unsigned long len2 = (unsigned long)divisor._primePowers.size(); unsigned long maxLen = (len1 > len2 ? len1 : len2); unsigned long i = 0; while (i < maxLen) { int p1 = (i < len1 ? _primePowers[i] : 0); int p2 = (i < len2 ? divisor._primePowers[i] : 0); if (p1 < p2) { return false; } i = i + 1; } return true; } std::string toString() const { bool allZero = true;//first check if its just 1 unsigned long idx = 0; while (idx < (unsigned long)_primePowers.size()) { if (_primePowers[idx] != 0) { allZero = false; break; } idx = idx + 1; } if (allZero) { return "1"; } std::string s = ""; bool firstTerm = true; unsigned long prime = 2;// start with 2 unsigned long i = 0; while (i < (unsigned long)_primePowers.size()) { int power = _primePowers[i]; if (power > 0) { if (!firstTerm) { s = s + " * "; } firstTerm = false; s = s + numberToString(prime); if (power > 1) { s = s + "^"; s = s + numberToString(power); } } if (prime == 2) //next prime { prime = 3; } else { prime = prime + 2; while (!isPrime(prime)) { prime = prime + 2; } } i = i + 1; } return s; } const std::vector<int>& primePowers() const noexcept { return _primePowers; } protected: std::vector<int> _primePowers; void trimZeros() { while (!_primePowers.empty() && _primePowers[_primePowers.size() - 1] == 0) { _primePowers.pop_back(); } } bool isPrime(unsigned long n) const { if (n < 2) { return false; } if (n == 2) { return true; } if (n % 2 == 0) { return false; } unsigned long i = 3; while (i * i <= n) { if (n % i == 0) { return false; } i = i + 2; } return true; } std::string numberToString(long n) const { if (n == 0) { return "0"; } bool negative = false; if (n < 0) { negative = true; n = -n; } std::string rev = ""; while (n > 0) { long digit = n % 10; char c = (char)('0' + digit); rev.push_back(c); n = n / 10; } std::string result = ""; if (negative) { result.push_back('-'); } long i = (long)rev.size() - 1; while (i >= 0) { result.push_back(rev[(unsigned long)i]); i = i - 1; } return result; } }; #endif //INITEGERP_H Loading
integerP.cpp 0 → 100644 +313 −0 Original line number Diff line number Diff line #ifndef INITEGERP_H #define INITEGERP_H #include <vector> #include <string> class IntegerP { public: IntegerP() { } IntegerP(unsigned long lnum) { if (lnum == 0) { lnum = 1; } unsigned long n = lnum; unsigned long prime = 2; while (n > 1) { int power = 0; // exponent of current prime at, count how many times it divides while (n % prime == 0) { n = n / prime; power += 1; } _primePowers.push_back(power); // next prime if (prime == 2) { prime = 3; } else { prime = prime + 2;//odd nums while (!isPrime(prime)) { prime = prime + 2;//skip non pimes } } } } IntegerP(const std::vector<int> &pBasis) { _primePowers = pBasis; } static IntegerP valueOf(const unsigned long lnum) { return IntegerP(lnum); } static IntegerP valueOf(const std::vector<int> &pBasis) { return IntegerP(pBasis); } IntegerP operator*(const IntegerP &multiplicand) const //multiplies two numbers { IntegerP result; unsigned long len1 = (unsigned long)_primePowers.size(); unsigned long len2 = (unsigned long)multiplicand._primePowers.size(); unsigned long maxLen = (len1 > len2 ? len1 : len2); result._primePowers.resize(maxLen); //result exponents unsigned long i = 0; while (i < maxLen) { int p1 = (i < len1 ? _primePowers[i] : 0); int p2 = (i < len2 ? multiplicand._primePowers[i] : 0); result._primePowers[i] = p1 + p2; i = i + 1; } return result; } IntegerP operator/(const IntegerP &divisor) const { IntegerP result; unsigned long len1 = (unsigned long)_primePowers.size(); unsigned long len2 = (unsigned long)divisor._primePowers.size(); unsigned long maxLen = (len1 > len2 ? len1 : len2); result._primePowers.resize(maxLen); unsigned long i = 0; while (i < maxLen) { int p1 = (i < len1 ? _primePowers[i] : 0); int p2 = (i < len2 ? divisor._primePowers[i] : 0); result._primePowers[i] = p1 - p2; i = i + 1; } return result; } bool operator==(const IntegerP &other) const { IntegerP a = *this; IntegerP b = other; a.trimZeros(); b.trimZeros(); //trim on copies if (a._primePowers.size() != b._primePowers.size()) { return false; } unsigned long len = (unsigned long)a._primePowers.size(); unsigned long i = 0; while (i < len) { if (a._primePowers[i] != b._primePowers[i]) { return false; } i = i + 1; } return true; } long trunc() const { long value = 1;//running product long maxVal = 9223372036854775807L;// max for 64 bit unsigned long prime = 2; // start at 2 and go through all primes used unsigned long i = 0; while (i < (unsigned long)_primePowers.size()) { int power = _primePowers[i]; int k = 0; while (k < power) { if (value != 0 && prime != 0) // if it goes past maxval { long limit = maxVal / (long)prime; if (value > limit) { return maxVal; } } value = value * (long)prime; k = k + 1; } if (prime == 2) //next prime { prime = 3; } else { prime = prime + 2; while (!isPrime(prime)) { prime = prime + 2; } } i = i + 1; } return value; } bool divisibleBy(const IntegerP &divisor) const { unsigned long len1 = (unsigned long)_primePowers.size(); unsigned long len2 = (unsigned long)divisor._primePowers.size(); unsigned long maxLen = (len1 > len2 ? len1 : len2); unsigned long i = 0; while (i < maxLen) { int p1 = (i < len1 ? _primePowers[i] : 0); int p2 = (i < len2 ? divisor._primePowers[i] : 0); if (p1 < p2) { return false; } i = i + 1; } return true; } std::string toString() const { bool allZero = true;//first check if its just 1 unsigned long idx = 0; while (idx < (unsigned long)_primePowers.size()) { if (_primePowers[idx] != 0) { allZero = false; break; } idx = idx + 1; } if (allZero) { return "1"; } std::string s = ""; bool firstTerm = true; unsigned long prime = 2;// start with 2 unsigned long i = 0; while (i < (unsigned long)_primePowers.size()) { int power = _primePowers[i]; if (power > 0) { if (!firstTerm) { s = s + " * "; } firstTerm = false; s = s + numberToString(prime); if (power > 1) { s = s + "^"; s = s + numberToString(power); } } if (prime == 2) //next prime { prime = 3; } else { prime = prime + 2; while (!isPrime(prime)) { prime = prime + 2; } } i = i + 1; } return s; } const std::vector<int>& primePowers() const noexcept { return _primePowers; } protected: std::vector<int> _primePowers; void trimZeros() { while (!_primePowers.empty() && _primePowers[_primePowers.size() - 1] == 0) { _primePowers.pop_back(); } } bool isPrime(unsigned long n) const { if (n < 2) { return false; } if (n == 2) { return true; } if (n % 2 == 0) { return false; } unsigned long i = 3; while (i * i <= n) { if (n % i == 0) { return false; } i = i + 2; } return true; } std::string numberToString(long n) const { if (n == 0) { return "0"; } bool negative = false; if (n < 0) { negative = true; n = -n; } std::string rev = ""; while (n > 0) { long digit = n % 10; char c = (char)('0' + digit); rev.push_back(c); n = n / 10; } std::string result = ""; if (negative) { result.push_back('-'); } long i = (long)rev.size() - 1; while (i >= 0) { result.push_back(rev[(unsigned long)i]); i = i - 1; } return result; } }; #endif //INITEGERP_H