<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Berechnung der ersten 20 Mersenne Primzahlen]]></title><description><![CDATA[<p>Das Problem ist hauptsächlich das Überprüfen ob eine Zahl Primzahl ist oder nicht. Für enorm große Zahlen wird das schwierige Aufgabe. Ich benutze &quot;long double&quot;.<br />
Nach etwa 12 Minuten abwarten schließe ich das Programm - so lange kann es nicht dauern, oder?</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;vector&gt;
#include &lt;algorithm&gt;
#include &lt;cmath&gt;
using namespace std;

bool is_prime(long double a) {
	for(long double d = 2; d &lt; floor(a/2 + 1); ++d)
		if(!fmod(a, d))
			return false;
	return true;
}

template &lt;class Large&gt;
class primes_generator {
	Large cp;
public:
	primes_generator()
		:cp(2) {}
	Large operator() () {
		Large tp = cp;
		while(!is_prime(tp))
			++tp;
		cp = tp + 1;
		return tp;
	}
};

template &lt;class ExtraLarge, class Large&gt;
ExtraLarge mnu(Large n) {
	ExtraLarge t = 2;
	for(Large i = 1; i &lt; n; ++i)
		t *= 2;
	return t - 1;
}

int main(int, char**) {
	vector&lt;unsigned&gt; primes(4423);
	generate(primes.begin(), primes.end(), primes_generator&lt;unsigned&gt;());
	vector&lt;long double&gt; mn;
	transform(primes.begin(), primes.end(), back_inserter(mn), mnu&lt;long double, unsigned&gt;);
	vector&lt;long double&gt; mp;
	remove_copy_if(mn.begin(), mn.end(), back_inserter(mp), is_prime);
	cout &lt;&lt; &quot;Mersenne primes: &quot; &lt;&lt; endl;
	copy(mp.begin(), mp.end(), ostream_iterator&lt;long double&gt;(cout, &quot;\n&quot;));
	getchar();
	return 0;
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/topic/176708/berechnung-der-ersten-20-mersenne-primzahlen</link><generator>RSS for Node</generator><lastBuildDate>Sat, 19 Sep 2026 14:41:28 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/176708.rss" rel="self" type="application/rss+xml"/><pubDate>Fri, 23 Mar 2007 21:34:55 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Berechnung der ersten 20 Mersenne Primzahlen on Fri, 23 Mar 2007 21:34:55 GMT]]></title><description><![CDATA[<p>Das Problem ist hauptsächlich das Überprüfen ob eine Zahl Primzahl ist oder nicht. Für enorm große Zahlen wird das schwierige Aufgabe. Ich benutze &quot;long double&quot;.<br />
Nach etwa 12 Minuten abwarten schließe ich das Programm - so lange kann es nicht dauern, oder?</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;vector&gt;
#include &lt;algorithm&gt;
#include &lt;cmath&gt;
using namespace std;

bool is_prime(long double a) {
	for(long double d = 2; d &lt; floor(a/2 + 1); ++d)
		if(!fmod(a, d))
			return false;
	return true;
}

template &lt;class Large&gt;
class primes_generator {
	Large cp;
public:
	primes_generator()
		:cp(2) {}
	Large operator() () {
		Large tp = cp;
		while(!is_prime(tp))
			++tp;
		cp = tp + 1;
		return tp;
	}
};

template &lt;class ExtraLarge, class Large&gt;
ExtraLarge mnu(Large n) {
	ExtraLarge t = 2;
	for(Large i = 1; i &lt; n; ++i)
		t *= 2;
	return t - 1;
}

int main(int, char**) {
	vector&lt;unsigned&gt; primes(4423);
	generate(primes.begin(), primes.end(), primes_generator&lt;unsigned&gt;());
	vector&lt;long double&gt; mn;
	transform(primes.begin(), primes.end(), back_inserter(mn), mnu&lt;long double, unsigned&gt;);
	vector&lt;long double&gt; mp;
	remove_copy_if(mn.begin(), mn.end(), back_inserter(mp), is_prime);
	cout &lt;&lt; &quot;Mersenne primes: &quot; &lt;&lt; endl;
	copy(mp.begin(), mp.end(), ostream_iterator&lt;long double&gt;(cout, &quot;\n&quot;));
	getchar();
	return 0;
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1251424</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1251424</guid><dc:creator><![CDATA[khalderon]]></dc:creator><pubDate>Fri, 23 Mar 2007 21:34:55 GMT</pubDate></item><item><title><![CDATA[Reply to Berechnung der ersten 20 Mersenne Primzahlen on Sat, 24 Mar 2007 01:23:23 GMT]]></title><description><![CDATA[<p>doppelpost sry, plz den hier löschen</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1251476</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1251476</guid><dc:creator><![CDATA[Shinja]]></dc:creator><pubDate>Sat, 24 Mar 2007 01:23:23 GMT</pubDate></item><item><title><![CDATA[Reply to Berechnung der ersten 20 Mersenne Primzahlen on Sat, 24 Mar 2007 08:58:22 GMT]]></title><description><![CDATA[<p>Hmm, als selbst Anfänger 5. Dinge:</p>
<p>1. geh bem primes_generator ab der 3 in 2er Schritten. Die geraden Zahlen kannst du eh alle überspringen.<br />
2. bei is_prime ebenfalls erst durch 2 testen, und dann ab 3 in 2er Schritten um die geraden Zahlen zu überspringen.<br />
3. geh bei is_prime nur bis d*d&lt;a+1.<br />
4. ich kann mir vorstellen, dass double eventuell zu Problemen führen könnte, bin mir aber nicht sicher (ich kenne fmod nicht)<br />
5. anstelle von</p>
<pre><code class="language-cpp">vector&lt;unsigned&gt; primes(4423);
</code></pre>
<p>würde ich</p>
<pre><code class="language-cpp">vector&lt;unsigned&gt; primes;
primes.reserve(4423);
</code></pre>
<p>nehmen. Sollte auch eine Kleinigkeit bringen, da bei reserve keine default construktoren aufgerufen werden (obs bei build-in types was bringt weisz ich aber nicht)<br />
6. deine Funtion mnu rechnet doch im Grunde die n+1te Potenz von 2, oder? Dafür gibt es auch eine std Funktion, nämlich pow(2,n+1). Bei der Übergabe musst du da natürlich bind_first benutzen.<br />
Wenn du es trotzdem selbst schreiben willst (ungetestet):</p>
<pre><code class="language-cpp">template &lt;class ExtraLarge, class Large&gt;
ExtraLarge mnu(Large n) {
    ExtraLarge t=2;
    while(n&gt;0){
        if(n%2==0){
            t*=t;
            n/=2;
        }
        else{
            t*=2;
            --n;
        }
    }
    return t;
}
</code></pre>
<p>EDIT: ich hab was vergessen: du speicherst ja eh alle Primzahlen ab! Da reicht es dann, wenn du immer durch alle vorher gefunden Primzahlen zu dividieren versuchst, die kleiner sind als die Wurzel aus der aktuellen Zahl.</p>
<p>Ich würde zu einer eigenen Klasse raten.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1251478</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1251478</guid><dc:creator><![CDATA[Shinja]]></dc:creator><pubDate>Sat, 24 Mar 2007 08:58:22 GMT</pubDate></item><item><title><![CDATA[Reply to Berechnung der ersten 20 Mersenne Primzahlen on Sat, 24 Mar 2007 09:43:39 GMT]]></title><description><![CDATA[<p>Ich erlaube mir mal einen Doppelpost. Ich hatte selbst noch kein primzahlenprogramm und habe deins mal Übungsweis geschrieben, o wie ich es versuchen würde. Ich bin mir nicht sicher ob es korrekt ist oder nicht, aber versuchen kann mans ja mal. Ich habe ledeglich das aussortieren von einigen am Ende weggelassen, denn ich denke es liegt daran, dass dein Programm nicht geht: unsigned double ist zu klein, um diese Zahlen zu halten. Ich bekomme sehr früh #INF als Ausgabe. Daher läuft dein remove_copy_if am Ende wohl so fast unendlich lange. Du musst dir also einen gröszeren Datentyp suchen.</p>
<p>Hier der Code:</p>
<p>prim.h</p>
<pre><code class="language-cpp">#ifndef PRIMZAHLEN_H
#define PRIMZAHLEN_H

#include &lt;deque&gt;

class Prim{
	std::deque&lt;unsigned long&gt; prims;
	bool isprim(unsigned long cand);
public:
	Prim(){prims.push_back(2);prims.push_back(3);}
	unsigned long calcprim(size_t n);
	const std::deque&lt;unsigned long&gt;&amp; getallprim(){return prims;}
};

#endif //PRIMZAHLEN_H
</code></pre>
<p>prim.cpp</p>
<pre><code class="language-cpp">#include &quot;prim.h&quot;
#include &lt;deque&gt;
#include &lt;assert.h&gt;

using namespace std;

bool Prim::isprim(unsigned long cand){
	for(size_t i=0;prims[i]*prims[i]&lt;=cand;++i)
		if(cand%prims[i]==0)
			return false;
	return true;
}

unsigned long Prim::calcprim(size_t n){
	assert(n&gt;0);
	if(n&gt;prims.size())
		for(size_t i=prims.size();i&lt;n;++i){
			unsigned long cand;
			for(cand=prims[prims.size()-1]+2;!isprim(cand);cand+=2);
			prims.push_back(cand);
		}
	return prims[n-1];
}
</code></pre>
<p>main.cpp</p>
<pre><code class="language-cpp">#include &quot;prim.h&quot;
#include &lt;fstream&gt;
#include &lt;deque&gt;
#include &lt;algorithm&gt;

using namespace std;

long double mnu(unsigned long n){
	long double t=2;
	while(n&gt;0){
        if(n%2==0){
            t*=t;
            n/=2;
        }
        else{
            t*=2;
            --n;
        }
	}
    return t-1;
}

int main(){
	Prim prim;
	prim.calcprim(4432);
	deque&lt;long double&gt; mers;
	transform(prim.getallprim().begin(),prim.getallprim().end(),back_inserter(mers),mnu);
	ofstream out(&quot;mersenne.txt&quot;);
	copy(mers.begin(),mers.end(),ostream_iterator&lt;long double&gt;(out,&quot;\n&quot;));
	return 0;
}
</code></pre>
<p>Entschuldige bitte, dass ich das hier einfach so als Eigenzweckübung missbrauche.<br />
Habe ich noch Fehler in meinem Programm? Wenn ja bitte sagen.<br />
Und was war nochmal der Header für size_t? Ich glaube ich habe den jetzt inkludiert weil er wohl in deque inkludiert ist, sollte ihn aber wohl besser selbst nochmal inkludieren.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1251517</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1251517</guid><dc:creator><![CDATA[Shinja]]></dc:creator><pubDate>Sat, 24 Mar 2007 09:43:39 GMT</pubDate></item><item><title><![CDATA[Reply to Berechnung der ersten 20 Mersenne Primzahlen on Sat, 24 Mar 2007 14:25:47 GMT]]></title><description><![CDATA[<p>Shinja, manche von deinen Bemerkungen hab ich übernommen. Trotzdem scheint es mir zu sein, dass du Mersenne Primzahlen mit Mersenne Numbers verwechselt hast. Nur die Prim-Mersenne Numbers sind die s.g. Mersenne Primes.<br />
Also, ich erkläre mein Algorithmus noch ein Mal:<br />
1. Nach Voraussetzung kennen wir, dass die 20. MP bei n=4,423 erfolgt. Ergo, berechnen wir die ersten 4,423 Primzahlen.<br />
2. Wir müssen die MNu berechnen, nach der Formel 2<sup>n</sup>-1.<br />
3. Aus den MNu's entnehmen wir nur die Primzahlen, also das sind unsere beliebte MP's. Aus allen 4 423 MNu soll es genau 20 MP geben (die letzte ist MP mit Sicherheit!).</p>
<p>So einfach kann es nicht sein. Dein Vorschlag sieht leider viel komplizierter und deshalb hab ich Angst ihn auszuprobieren <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f62e.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--face_with_open_mouth"
      title=":open_mouth:"
      alt="😮"
    /></p>
<p>Hier die neue Code:</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;vector&gt;
#include &lt;algorithm&gt;
#include &lt;cmath&gt;
using namespace std;

bool is_prime(long double a) {
	if(a &lt;= 3)
		return true;
	for(long double d = 5; d*d &lt; a + 1; d += 2)
		if(!fmod(a, d))
			return false;
	return true;
}

template &lt;class Large&gt;
class primes_generator {
	Large cp;
public:
	primes_generator()
		:cp(2) {}
	Large operator() () {
		Large tp = cp;
		while(!is_prime(tp))
			++tp;
		cp = tp + 1;
		return tp;
	}
};

template &lt;class ExtraLarge, class Large&gt;
ExtraLarge mnu(Large n) {
	ExtraLarge t = 2;
	for(Large i = 1; i &lt; n; ++i)
		t *= 2;
	return t - 1;
}

int main(int, char**) {
	cout &lt;&lt; &quot;reserving space for prime numbers...&quot;;
	vector&lt;long unsigned&gt; primes(4423);
	cout &lt;&lt; &quot; ok&quot; &lt;&lt; endl &lt;&lt; &quot;calculating prime numbers...&quot;;
	generate(primes.begin(), primes.end(), primes_generator&lt;long unsigned&gt;());
	vector&lt;long double&gt; mn;
	cout &lt;&lt; &quot; ok&quot; &lt;&lt; endl &lt;&lt; &quot;generating Mersenne numbers...&quot;;
	transform(primes.begin(), primes.end(), back_inserter(mn), mnu&lt;long double, long unsigned&gt;);
	cout &lt;&lt; &quot; ok&quot; &lt;&lt; endl &lt;&lt; &quot;determing the Mersenne primes...&quot;;
	vector&lt;long double&gt; mp;
	remove_copy_if(mn.begin(), mn.end(), back_inserter(mp), is_prime);
	cout &lt;&lt; &quot;Mersenne primes: &quot; &lt;&lt; endl;
	copy(mp.begin(), mp.end(), ostream_iterator&lt;long double&gt;(cout, &quot;\n&quot;));
	getchar();
	return 0;
}
</code></pre>
<p>P.S. Im Wiki steht, dass die 20 MP aus 1,332 Ziffern besteht. Kann &quot;long double&quot; so was behandeln?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1251647</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1251647</guid><dc:creator><![CDATA[khalderon]]></dc:creator><pubDate>Sat, 24 Mar 2007 14:25:47 GMT</pubDate></item><item><title><![CDATA[Reply to Berechnung der ersten 20 Mersenne Primzahlen on Sat, 24 Mar 2007 15:21:08 GMT]]></title><description><![CDATA[<p>Nein, kann es glaube ich nicht. Würde mich sehr wundern.</p>
<p>Was ich ausgebe sind tatsächlich die Mersenne Numbers. Ich habe ja geschrieben warum ich die nicht umgerechnet habe: ab der 69. Zahl von den 4000 und etwas sind sie schon #INF. Ich denke da liegt dann eben auch das Problem beim remove_copy_if() am Ende: is_prime läuft so ewig lange bei all den Zahlen weil alle Zahlen #INF sind.</p>
<p>Meine Berechnung sollte aber definitiv schneller sein. Ich erhalte die ersten 1 Million Primzahlen in 19 Sekunden. Es geht natürich noch viel schneller wenn sich die guten Programmierer hier mal ans Werk setzen, aber für mich reicht das mal.</p>
<pre><code class="language-cpp">template &lt;class Large&gt;
class primes_generator {
    Large cp;
public:
    primes_generator()
        :cp(3) {}
    Large operator() () {
        Large tp = cp;
        while(!is_prime(tp))
            tp+=2;
        cp = tp + 2;
        return tp;
    }
};
</code></pre>
<p>So, das Einzige wo du jetzt extra machen musst ist 2 am Anfang per Hand hinzuzufügen, bevor der generator los läuft. Braucht schonmal wieder nur halb so lang.</p>
<p>Auszerdem sollte dein is_prime() lieber einmal durch 2 testen und dann ab 3 in 2er schritten. Ansonsten gibts probleme bei 2er potenzen nachher.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1251671</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1251671</guid><dc:creator><![CDATA[Shinja]]></dc:creator><pubDate>Sat, 24 Mar 2007 15:21:08 GMT</pubDate></item><item><title><![CDATA[Reply to Berechnung der ersten 20 Mersenne Primzahlen on Sat, 24 Mar 2007 15:18:38 GMT]]></title><description><![CDATA[<p>Voila! Ich hab's gefunden!</p>
<pre><code class="language-cpp">cout &lt;&lt; &quot; ok&quot; &lt;&lt; endl &lt;&lt; &quot;generating Mersenne numbers...&quot;;
	transform(primes.begin(), primes.end(), back_inserter(mn), mnu&lt;long double, long unsigned&gt;);
	cout &lt;&lt; &quot; ok&quot; &lt;&lt; endl &lt;&lt; &quot;determing the Mersenne primes...&quot; &lt;&lt; endl;
	remove_copy_if(mn.begin(), mn.end(), ostream_iterator&lt;long double&gt;(cout, &quot;\n&quot;), not1(ptr_fun(is_prime)));
	cout &lt;&lt; &quot;done.&quot;;
</code></pre>
<p>Das Problem war, dass &quot;remove_copy_if&quot; die Funktion negiert. Jetzt sollte es funkzionieren...<br />
Nach etwa 20 Minuten sind die ersten 15 MP da!</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1251674</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1251674</guid><dc:creator><![CDATA[khalderon]]></dc:creator><pubDate>Sat, 24 Mar 2007 15:18:38 GMT</pubDate></item></channel></rss>