#include #include #include #include #include using namespace std; const unsigned long N = 0x100000000; class Primzahlen { private: static bitset primes; public: static void init() { primes.set(); primes.reset(0); primes.reset(1); for (unsigned long k = 2; k*k < N; k++) if (primes[k]) for (unsigned long i = k; i * k < N; i++) primes.reset(i*k); } static bool ist_primzahl(unsigned long n) { if (n < N) return primes[n]; else if (N * N > n) { for (unsigned long k = 2; k < N; k++) if (primes[k] && n % k == 0) return false; return true; } else { ostringstream err; err << n << " lies outside of acceptable range for ist_primzahl [0.." << N*N << ")"; throw domain_error(err.str()); } } }; bitset Primzahlen::primes{}; class Primfaktor { public: unsigned long p, k; Primfaktor(unsigned long p_ = 0, unsigned long k_ = 1): p(p_), k(k_) {} friend ostream& operator<<(ostream& stream, Primfaktor pf) { stream << pf.p; if (pf.k != 1) stream << "^" << pf.k; return stream; } }; class Primfaktorzerlegung { private: list factors; public: Primfaktorzerlegung(unsigned long n = 1) { for (unsigned long p = 2; p * p <= n && p * p < N; p++) { if (!Primzahlen::ist_primzahl(p)) continue; unsigned long k = 0; while (n % p == 0) { k++; n /= p; } if (k >= 1) factors.push_back(Primfaktor{p, k}); } if (n != 1) factors.push_back(Primfaktor{n}); } operator unsigned long() { unsigned long res = 1; for (Primfaktor pf: factors) while (pf.k-- > 0) res *= pf.p; return res; } friend bool ist_primzahl(const Primfaktorzerlegung& pfz) { if (pfz.factors.empty()) return false; list::const_iterator it = pfz.factors.begin(); return it->k == 1 && ++it == pfz.factors.end(); } friend ostream& operator<<(ostream& stream, Primfaktorzerlegung pfz) { if (pfz.factors.empty()) return stream << "1"; for (list::iterator i = pfz.factors.begin(); i != pfz.factors.end(); i++) { if (i != pfz.factors.begin()) stream << "*"; stream << *i; } return stream; } }; int main() { Primzahlen::init(); unsigned long zweip = 1; while (true) { Primfaktorzerlegung pfz{zweip}; cout << setw(20) << zweip; if (ist_primzahl(pfz)) cout << " Mersenne-Primzahl: "; else cout << ": "; cout << pfz << endl; if (zweip != static_cast(pfz)) cout << "Typumwandlung (" << static_cast(pfz) << ") entspricht nicht Argument (" << zweip << ")" << endl; unsigned long old_zweip = zweip; zweip = (zweip << 1) | 1; if (zweip > N * (N - 1) + (N - 1) || old_zweip == zweip) break; } }