<?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[C++11-PRNGs]]></title><description><![CDATA[<p>Hallo.</p>
<p>Nachdem sich einige Programmierer in diesem Forum in die C++11-PRNGs verguckt haben, möchte ich dazu einige Dinge sagen / fragen.</p>
<ol>
<li><code>std::uniform_int_distribution</code> löst in einem gewöhnlichen praktischen Fall 60% - 70% mehr Aufrufe des Generators aus wie die naive Modulo-Methode. Diese Klasse ist in der MSVC-Standardbibliothek so implementiert, dass sie nicht einmal garantiert terminiert. Laut <a href="http://www.cplusplus.com/reference/random/uniform_int_distribution/operator()/" rel="nofollow">dem hier</a> oder <a href="http://en.cppreference.com/w/cpp/numeric/random/uniform_int_distribution/operator()" rel="nofollow">dem hier</a> sollte die Anzahl der Aufrufe jedoch konstant sein.</li>
</ol>
<p>2. Ich habe eine gleichverteilte Engine geschrieben, die auf einer Permutation basiert. Dann hab ich mir ein paar Werte mit <code>std::uniform_int_distribution</code> generieren lassen. Diese sind zu meiner Enttäuschung äusserst schlecht verteilt. Seht selbst:</p>
<pre><code>0: 0		 1: 0		 2: 0		 3: 0		 4: 0		 5: 0		 6: 96774		 7: 0		 8: 0		 9: 0
10: 0		11: 0		12: 0		13: 0		14: 0		15: 0		16: 96774		17: 0		18: 0		19: 0
20: 0		21: 0		22: 0		23: 0		24: 0		25: 0		26: 96774		27: 0		28: 0		29: 0
30: 0		31: 0		32: 0		33: 0		34: 0		35: 0		36: 96774		37: 0		38: 0		39: 0
40: 0		41: 0		42: 0		43: 0		44: 0		45: 0		46: 96774		47: 0		48: 0		49: 0
50: 0		51: 0		52: 0		53: 0		54: 0		55: 0		56: 96774		57: 0		58: 0		59: 0
60: 0		61: 0		62: 0		63: 0		64: 0		65: 0		66: 129033		67: 0		68: 0		69: 0
70: 0		71: 0		72: 0		73: 0		74: 0		75: 0		76: 96774		77: 0		78: 0		79: 0
80: 0		81: 0		82: 0		83: 0		84: 0		85: 0		86: 96774		87: 0		88: 0		89: 0
90: 0		91: 0		92: 0		93: 0		94: 0		95: 0		96: 96775		97: 0		98: 0		99: 0
</code></pre>
<p>Wieso ist das so?</p>
<p>3. Wieso ist der Algorithmus KISS / RKISS nicht implementiert? Dieser ist viel schneller / kleiner / besser als der Mersenne Twister und sogar kryptographisch sicher.</p>
<p>4. Wieso werden die Zustände der Engines in dezimaler Schreibweise ausgegeben? Gibt es einen direkten Weg um den Zustand speichersparend abzuspeichern oder wenigstens auf den internen Zustand zugreifen zu können? Einen <code>streambuf</code> / <code>num_put</code> / ... (was auch immer dafür benötigt ist, ich weiss es ehrlich gesagt nicht) zu schreiben halte ich für nicht sehr direkt.</p>
<p>5. Wieso ist von <code>result_type</code> , <code>min()</code> , etc. bei (eigenen) Generatoren gefordert, dass sie Teil der Klasse sind? Meiner Meinung nach bietet sich hier sowas wie <code>generator_traits</code> mehr an.</p>
<p>6. Wieso ist <code>discard()</code> eine Methode? Diese Funktion ist ein idealer Kandidat für eine freie Funktion. Nicht nur weil sie nicht einmal auf private Daten zugreift, sondern auch weil man sie dann für eigene Generatoren nicht erneut implementieren muss.</p>
<p>Gruss.</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/326913/c-11-prngs</link><generator>RSS for Node</generator><lastBuildDate>Thu, 09 Jul 2026 20:24:19 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/326913.rss" rel="self" type="application/rss+xml"/><pubDate>Mon, 14 Jul 2014 13:48:43 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to C++11-PRNGs on Mon, 14 Jul 2014 13:48:43 GMT]]></title><description><![CDATA[<p>Hallo.</p>
<p>Nachdem sich einige Programmierer in diesem Forum in die C++11-PRNGs verguckt haben, möchte ich dazu einige Dinge sagen / fragen.</p>
<ol>
<li><code>std::uniform_int_distribution</code> löst in einem gewöhnlichen praktischen Fall 60% - 70% mehr Aufrufe des Generators aus wie die naive Modulo-Methode. Diese Klasse ist in der MSVC-Standardbibliothek so implementiert, dass sie nicht einmal garantiert terminiert. Laut <a href="http://www.cplusplus.com/reference/random/uniform_int_distribution/operator()/" rel="nofollow">dem hier</a> oder <a href="http://en.cppreference.com/w/cpp/numeric/random/uniform_int_distribution/operator()" rel="nofollow">dem hier</a> sollte die Anzahl der Aufrufe jedoch konstant sein.</li>
</ol>
<p>2. Ich habe eine gleichverteilte Engine geschrieben, die auf einer Permutation basiert. Dann hab ich mir ein paar Werte mit <code>std::uniform_int_distribution</code> generieren lassen. Diese sind zu meiner Enttäuschung äusserst schlecht verteilt. Seht selbst:</p>
<pre><code>0: 0		 1: 0		 2: 0		 3: 0		 4: 0		 5: 0		 6: 96774		 7: 0		 8: 0		 9: 0
10: 0		11: 0		12: 0		13: 0		14: 0		15: 0		16: 96774		17: 0		18: 0		19: 0
20: 0		21: 0		22: 0		23: 0		24: 0		25: 0		26: 96774		27: 0		28: 0		29: 0
30: 0		31: 0		32: 0		33: 0		34: 0		35: 0		36: 96774		37: 0		38: 0		39: 0
40: 0		41: 0		42: 0		43: 0		44: 0		45: 0		46: 96774		47: 0		48: 0		49: 0
50: 0		51: 0		52: 0		53: 0		54: 0		55: 0		56: 96774		57: 0		58: 0		59: 0
60: 0		61: 0		62: 0		63: 0		64: 0		65: 0		66: 129033		67: 0		68: 0		69: 0
70: 0		71: 0		72: 0		73: 0		74: 0		75: 0		76: 96774		77: 0		78: 0		79: 0
80: 0		81: 0		82: 0		83: 0		84: 0		85: 0		86: 96774		87: 0		88: 0		89: 0
90: 0		91: 0		92: 0		93: 0		94: 0		95: 0		96: 96775		97: 0		98: 0		99: 0
</code></pre>
<p>Wieso ist das so?</p>
<p>3. Wieso ist der Algorithmus KISS / RKISS nicht implementiert? Dieser ist viel schneller / kleiner / besser als der Mersenne Twister und sogar kryptographisch sicher.</p>
<p>4. Wieso werden die Zustände der Engines in dezimaler Schreibweise ausgegeben? Gibt es einen direkten Weg um den Zustand speichersparend abzuspeichern oder wenigstens auf den internen Zustand zugreifen zu können? Einen <code>streambuf</code> / <code>num_put</code> / ... (was auch immer dafür benötigt ist, ich weiss es ehrlich gesagt nicht) zu schreiben halte ich für nicht sehr direkt.</p>
<p>5. Wieso ist von <code>result_type</code> , <code>min()</code> , etc. bei (eigenen) Generatoren gefordert, dass sie Teil der Klasse sind? Meiner Meinung nach bietet sich hier sowas wie <code>generator_traits</code> mehr an.</p>
<p>6. Wieso ist <code>discard()</code> eine Methode? Diese Funktion ist ein idealer Kandidat für eine freie Funktion. Nicht nur weil sie nicht einmal auf private Daten zugreift, sondern auch weil man sie dann für eigene Generatoren nicht erneut implementieren muss.</p>
<p>Gruss.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2408521</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2408521</guid><dc:creator><![CDATA[Fytch]]></dc:creator><pubDate>Mon, 14 Jul 2014 13:48:43 GMT</pubDate></item><item><title><![CDATA[Reply to C++11-PRNGs on Mon, 14 Jul 2014 14:04:15 GMT]]></title><description><![CDATA[<p>asfdlol schrieb:</p>
<blockquote>
<ol>
<li><code>std::uniform_int_distribution</code> löst in einem gewöhnlichen praktischen Fall 60% - 70% mehr Aufrufe des Generators aus wie die naive Modulo-Methode.</li>
</ol>
</blockquote>
<p>Ja und? Dafür sind die Ergebnisse gleichverteilt. Wenn du das nicht brauchst, nimmt du eben nicht <code>uniform_int_distribution</code> .</p>
<p>asfdlol schrieb:</p>
<blockquote>
<p>Diese Klasse ist in der MSVC-Standardbibliothek so implementiert, dass sie nicht einmal garantiert terminiert. Laut <a href="http://www.cplusplus.com/reference/random/uniform_int_distribution/operator()/" rel="nofollow">dem hier</a> oder <a href="http://en.cppreference.com/w/cpp/numeric/random/uniform_int_distribution/operator()" rel="nofollow">dem hier</a> sollte die Anzahl der Aufrufe jedoch konstant sein.</p>
</blockquote>
<p>Dass MSVC Bugs hat, ist ja etwas ganz neues..</p>
<p>asfdlol schrieb:</p>
<blockquote>
<p>2. Ich habe eine gleichverteilte Engine [...] zu meiner Enttäuschung äusserst schlecht verteilt.</p>
</blockquote>
<p>Aha.</p>
<p>asfdlol schrieb:</p>
<blockquote>
<p>3. Wieso ist der Algorithmus KISS / RKISS nicht implementiert? Dieser ist viel schneller / kleiner / besser als der Mersenne Twister und sogar kryptographisch sicher.</p>
</blockquote>
<p>Dein Proposal für die Standardisierung ist bestimmt sehr interessant, ich finde das gute Stück aber nirgends.</p>
<p>asfdlol schrieb:</p>
<blockquote>
<p>6. Wieso ist <code>discard()</code> eine Methode?</p>
</blockquote>
<p>Weil ein Generator die unter Umständen effizienter implementieren kann, wenn er nicht wirklich etwas generieren muss.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2408525</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2408525</guid><dc:creator><![CDATA[TyRoXx]]></dc:creator><pubDate>Mon, 14 Jul 2014 14:04:15 GMT</pubDate></item><item><title><![CDATA[Reply to C++11-PRNGs on Mon, 14 Jul 2014 14:32:23 GMT]]></title><description><![CDATA[<p>TyRoXx schrieb:</p>
<blockquote>
<p>Dein Proposal für die Standardisierung ist bestimmt sehr interessant, ich finde das gute Stück aber nirgends.</p>
</blockquote>
<p><a href="http://zuttobenkyou.wordpress.com/2012/05/01/kiss-2011-version-in-c-and-haskell/" rel="nofollow">http://zuttobenkyou.wordpress.com/2012/05/01/kiss-2011-version-in-c-and-haskell/</a></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2408532</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2408532</guid><dc:creator><![CDATA[PRND]]></dc:creator><pubDate>Mon, 14 Jul 2014 14:32:23 GMT</pubDate></item><item><title><![CDATA[Reply to C++11-PRNGs on Mon, 14 Jul 2014 14:32:47 GMT]]></title><description><![CDATA[<p>asfdlol schrieb:</p>
<blockquote>
<ol>
<li><code>std::uniform_int_distribution</code> löst in einem gewöhnlichen praktischen Fall 60% - 70% mehr Aufrufe des Generators aus wie die naive Modulo-Methode. Diese Klasse ist in der MSVC-Standardbibliothek so implementiert, dass sie nicht einmal garantiert terminiert. Laut <a href="http://www.cplusplus.com/reference/random/uniform_int_distribution/operator()/" rel="nofollow">dem hier</a> oder <a href="http://en.cppreference.com/w/cpp/numeric/random/uniform_int_distribution/operator()" rel="nofollow">dem hier</a> sollte die Anzahl der Aufrufe jedoch konstant sein.</li>
</ol>
</blockquote>
<p><em>Amortisiert</em> konstant. Die Implementation von Visual C++ kenne ich nicht, aber bereits ein naiver modulo-basierter Algorithmus hat diese Eigenschaft.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2408533</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2408533</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Mon, 14 Jul 2014 14:32:47 GMT</pubDate></item><item><title><![CDATA[Reply to C++11-PRNGs on Mon, 14 Jul 2014 21:58:58 GMT]]></title><description><![CDATA[<p>asfdlol schrieb:</p>
<blockquote>
<p>Ich habe eine gleichverteilte Engine geschrieben</p>
</blockquote>
<p>Könntest du die mal posten?</p>
<p>asfdlol schrieb:</p>
<blockquote>
<p>und sogar kryptographisch sicher.</p>
</blockquote>
<p>Hört sich interessant an, aber habe ich leider wenig zu gefunden bei einer schnellen Suche. Gibt's da was zu lesen?</p>
<p>asfdlol schrieb:</p>
<blockquote>
<p>Gibt es einen direkten Weg um den Zustand speichersparend abzuspeichern oder wenigstens auf den internen Zustand zugreifen zu können?</p>
</blockquote>
<p>Nein, weil's das Komitee mit der Portabilität mal wieder ein bisschen übertrieben hat.</p>
<p>asfdlol schrieb:</p>
<blockquote>
<p>5. Wieso ist von <code>result_type</code> , <code>min()</code> , etc. bei (eigenen) Generatoren gefordert, dass sie Teil der Klasse sind?</p>
</blockquote>
<p>Weil traits das ganze unnötig komplex machen würden.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2408642</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2408642</guid><dc:creator><![CDATA[cooky451]]></dc:creator><pubDate>Mon, 14 Jul 2014 21:58:58 GMT</pubDate></item><item><title><![CDATA[Reply to C++11-PRNGs on Tue, 15 Jul 2014 07:31:33 GMT]]></title><description><![CDATA[<p>TyRoXx schrieb:</p>
<blockquote>
<p>asfdlol schrieb:</p>
<blockquote>
<p>2. Ich habe eine gleichverteilte Engine [...] zu meiner Enttäuschung äusserst schlecht verteilt.</p>
</blockquote>
<p>Aha.</p>
</blockquote>
<p>Verfälschst du das Zitat absichtlich?</p>
<p>TyRoXx schrieb:</p>
<blockquote>
<p>asfdlol schrieb:</p>
<blockquote>
<p>3. Wieso ist der Algorithmus KISS / RKISS nicht implementiert? Dieser ist viel schneller / kleiner / besser als der Mersenne Twister und sogar kryptographisch sicher.</p>
</blockquote>
<p>Dein Proposal für die Standardisierung ist bestimmt sehr interessant, ich finde das gute Stück aber nirgends.</p>
</blockquote>
<p>Was meinst du damit? Ich hab ja nicht gesagt, dass ich sowas machen kann.</p>
<p>TyRoXx schrieb:</p>
<blockquote>
<p>asfdlol schrieb:</p>
<blockquote>
<p>6. Wieso ist <code>discard()</code> eine Methode?</p>
</blockquote>
<p>Weil ein Generator die unter Umständen effizienter implementieren kann, wenn er nicht wirklich etwas generieren muss.</p>
</blockquote>
<p>Ja, war zunächst auch mein Gedanke. Bei MSVC's Standardbibliothek ist das jedenfalls nicht der Fall. Und auch wenn es eine effiziente Version gibt, dann lässt sich die auch ohne Probleme im eine freie Funktion implementieren.</p>
<p>camper schrieb:</p>
<blockquote>
<p><em>Amortisiert</em> konstant.</p>
</blockquote>
<p>Huch, danke. Kannte ich nicht.</p>
<p>camper schrieb:</p>
<blockquote>
<p>Die Implementation von Visual C++ kenne ich nicht, aber bereits ein naiver modulo-basierter Algorithmus hat diese Eigenschaft.</p>
</blockquote>
<p>Ich bin mir nicht 100%ig sicher und gebe somit keine Garantie auf Richtigkeit, jedoch hat mich der folgende Code denken lassen, dass die Komplexität theoretisch unbeschränkt ist:</p>
<pre><code>for (; ; )
			{	// repeat until random value is in range
			_Udiff _Val = _Ref() - (_Urng::min)();

			if (_Val &lt;= _Bmask)
				return (_Val);
			}
</code></pre>
<p>Wobei <code>_Bmask</code> eine Bitmaske ist, die anhand der Zielmenge der Verteilung gewählt wurde.</p>
<p>cooky451 schrieb:</p>
<blockquote>
<p>Könntest du die mal posten?</p>
</blockquote>
<p>Natürlich (ist nur eine vereinfachte <code>std::shuffle_order_engine</code> ):</p>
<pre><code>template&lt;unsigned int Range&gt;
class PermutationEngine
{
public:
	typedef unsigned int result_type;

private:
	result_type Permutation[Range];
	std::size_t State;
	void Shuffle()
	{
		std::random_shuffle(std::begin(Permutation), std::end(Permutation));
	}

public:
	PermutationEngine()
		: State(0)
	{
		for(std::size_t i = 0; i &lt; Range; ++i)
		{
			Permutation[i] = i; // evtl. static_cast&lt;result_type&gt;(i)
		}
		Shuffle();
	}

	static /*constexpr*/ result_type min()
	{
		return 0;
	}
	static /*constexpr*/ result_type max()
	{
		return Range - 1;
	}

	result_type operator() ()
	{
		result_type Result = Permutation[State];
		if(++State == Range)
		{
			State = 0;
			Shuffle();
		}
		return Result;
	}
};
template&lt;&gt;
class PermutationEngine&lt;0&gt;;
</code></pre>
<p>Das soll auch keine echte Engine sein die man auch wirklich nutzt, sondern dient nur den Testzwecken.</p>
<p>cooky451 schrieb:</p>
<blockquote>
<p>Hört sich interessant an, aber habe ich leider wenig zu gefunden bei einer schnellen Suche. Gibt's da was zu lesen?</p>
</blockquote>
<p>Das was PRND schon gepostet hat.</p>
<p>cooky451 schrieb:</p>
<blockquote>
<p>asfdlol schrieb:</p>
<blockquote>
<p>Gibt es einen direkten Weg um den Zustand speichersparend abzuspeichern oder wenigstens auf den internen Zustand zugreifen zu können?</p>
</blockquote>
<p>Nein, weil's das Komitee mit der Portabilität mal wieder ein bisschen übertrieben hat.</p>
</blockquote>
<p>Schade. Wie macht ihr das denn?</p>
<p>cooky451 schrieb:</p>
<blockquote>
<p>Weil traits das ganze unnötig komplex machen würden.</p>
</blockquote>
<p>Das stimmt, komplexer wird es ein wenig. Naja, ich bin perfektionistisch und ärgere mich ein bisschen, wenn ich die selben Dinge zwei Mal in der Klasse habe (mit anderem Bezeichner).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2408655</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2408655</guid><dc:creator><![CDATA[Fytch]]></dc:creator><pubDate>Tue, 15 Jul 2014 07:31:33 GMT</pubDate></item><item><title><![CDATA[Reply to C++11-PRNGs on Tue, 15 Jul 2014 07:48:35 GMT]]></title><description><![CDATA[<p>asfdlol schrieb:</p>
<blockquote>
<p>TyRoXx schrieb:</p>
<blockquote>
<p>asfdlol schrieb:</p>
<blockquote>
<p>2. Ich habe eine gleichverteilte Engine [...] zu meiner Enttäuschung äusserst schlecht verteilt.</p>
</blockquote>
<p>Aha.</p>
</blockquote>
<p>Verfälschst du das Zitat absichtlich?</p>
</blockquote>
<p>Deine &quot;gleichverteilte Engine&quot; ist falsch. Natürlich liefert <code>uniform_int_distribution</code> damit Müll.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2408657</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2408657</guid><dc:creator><![CDATA[TyRoXx]]></dc:creator><pubDate>Tue, 15 Jul 2014 07:48:35 GMT</pubDate></item><item><title><![CDATA[Reply to C++11-PRNGs on Tue, 15 Jul 2014 07:53:36 GMT]]></title><description><![CDATA[<p>TyRoXx schrieb:</p>
<blockquote>
<p>Deine &quot;gleichverteilte Engine&quot; ist falsch. Natürlich liefert <code>uniform_int_distribution</code> damit Müll.</p>
</blockquote>
<p>Und wieso ist sie falsch?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2408658</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2408658</guid><dc:creator><![CDATA[Fytch]]></dc:creator><pubDate>Tue, 15 Jul 2014 07:53:36 GMT</pubDate></item><item><title><![CDATA[Reply to C++11-PRNGs on Tue, 15 Jul 2014 09:55:21 GMT]]></title><description><![CDATA[<p>asfdlol schrieb:</p>
<blockquote>
<p>Und auch wenn es eine effiziente Version gibt, dann lässt sich die auch ohne Probleme im eine freie Funktion implementieren.</p>
</blockquote>
<p>Eh... nö. Wie kommst du darauf? Als friend vielleicht, aber dass Memberfunktionen hier hübscher als friend gehacke sind sollte wohl klar sein.</p>
<p>asfdlol schrieb:</p>
<blockquote>
<p>Das was PRND schon gepostet hat.</p>
</blockquote>
<p>Also da habe ich jetzt nichts zur kryptographischen Sicherheit gefunden?</p>
<p>asfdlol schrieb:</p>
<blockquote>
<p>Schade. Wie macht ihr das denn?</p>
</blockquote>
<p>Es gibt die Möglichkeit den Seed und wie oft man discard()en muss zu speichern. Wenn das zu langsam ist muss man wohl in den sauren Apfel beißen und es selbst implementieren, aber ich meine dann scheint man ja eh recht spezielle Anforderungen an die Performance zu haben.</p>
<p>Ansonsten wegen der Engine, also wenn die die mit &lt;16&gt; instanziiere und eine uniform_int_distribution(0, 32) 50000 benutze kommt da bei mir (VS 2013) folgendes bei raus:</p>
<pre><code>0: 1432
1: 1324
2: 1364
3: 1382
4: 1334
5: 1329
6: 1438
7: 1622
8: 1641
9: 1598
10: 1570
11: 1630
12: 1629
13: 1667
14: 1585
15: 1600
16: 1655
17: 1447
18: 1415
19: 1322
20: 1355
21: 1382
22: 1376
23: 1368
24: 1668
25: 1551
26: 1651
27: 1650
28: 1608
29: 1602
30: 1636
31: 1662
32: 1507
</code></pre>
<p>Sind zwar ein paar &quot;Ausschläge&quot; bei die nicht ganz sauber aussehen, aber die würde ich dann mal frech auf das etwas eigenartige Verhalten deiner Engine schieben. (Innerhalb einer Periode kann eine Zahl nur genau ein mal vor kommen.)</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2408684</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2408684</guid><dc:creator><![CDATA[cooky451]]></dc:creator><pubDate>Tue, 15 Jul 2014 09:55:21 GMT</pubDate></item><item><title><![CDATA[Reply to C++11-PRNGs on Tue, 15 Jul 2014 11:13:58 GMT]]></title><description><![CDATA[<p>cooky451 schrieb:</p>
<blockquote>
<p>asfdlol schrieb:</p>
<blockquote>
<p>Und auch wenn es eine effiziente Version gibt, dann lässt sich die auch ohne Probleme im eine freie Funktion implementieren.</p>
</blockquote>
<p>Eh... nö. Wie kommst du darauf? Als friend vielleicht, aber dass Memberfunktionen hier hübscher als friend gehacke sind sollte wohl klar sein.</p>
</blockquote>
<p>Oder die Engine, für welche dies der Fall ist, bietet eine Methode an, die dann von der entsprechenden Spezialisierung der freien Funktion aufgerufen wird. Ist aber auch egal nun, ich bin das Boilerplate- <code>discard()</code> mit CRTP los geworden.</p>
<p>cooky451 schrieb:</p>
<blockquote>
<p>asfdlol schrieb:</p>
<blockquote>
<p>Das was PRND schon gepostet hat.</p>
</blockquote>
<p>Also da habe ich jetzt nichts zur kryptographischen Sicherheit gefunden?</p>
</blockquote>
<p>Okay, ich habe gerade <a href="http://eprint.iacr.org/2011/007.pdf" rel="nofollow">dieses Paper</a> hier gefunden, in welchem steht, dass KISS doch nicht kryptographisch sicher ist. Schade. Nichtsdestotrotz produziert KISS laut dem BigCrush-Test bessere Zufallszahlen wie der Mersenne-Twister.</p>
<p>cooky451 schrieb:</p>
<blockquote>
<p>[...]</p>
</blockquote>
<p>Oha, deine Ergebnisse sind ja um Welten besser als die meinen. Ich hab meinen Code des Tests leider wieder weggeworfen und weiss die exakten Testparameter nicht mehr... <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f644.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--face_with_rolling_eyes"
      title=":rolling_eyes:"
      alt="🙄"
    /> Vielleicht finde ich sie wieder heraus. Vielleicht habe ich aber auch bei der Auswertung gestern Quatsch gemacht, denn meine Ergebnisse sind schon so absonderlich, dass sie kaum glaubwürdig waren / sind. Könnte jedoch wetten, dass die Auswerung gestimmt hat.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2408704</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2408704</guid><dc:creator><![CDATA[Fytch]]></dc:creator><pubDate>Tue, 15 Jul 2014 11:13:58 GMT</pubDate></item><item><title><![CDATA[Reply to C++11-PRNGs on Tue, 15 Jul 2014 11:25:29 GMT]]></title><description><![CDATA[<p>asfdlol schrieb:</p>
<blockquote>
<p><code>std::uniform_int_distribution</code> generieren lassen. Diese sind zu meiner Enttäuschung äusserst schlecht verteilt. Seht selbst:</p>
<pre><code>0: 0		 1: 0		 2: 0		 3: 0		 4: 0		 5: 0		 6: 96774		 7: 0		 8: 0		 9: 0
10: 0		11: 0		12: 0		13: 0		14: 0		15: 0		16: 96774		17: 0		18: 0		19: 0
20: 0		21: 0		22: 0		23: 0		24: 0		25: 0		26: 96774		27: 0		28: 0		29: 0
30: 0		31: 0		32: 0		33: 0		34: 0		35: 0		36: 96774		37: 0		38: 0		39: 0
40: 0		41: 0		42: 0		43: 0		44: 0		45: 0		46: 96774		47: 0		48: 0		49: 0
50: 0		51: 0		52: 0		53: 0		54: 0		55: 0		56: 96774		57: 0		58: 0		59: 0
60: 0		61: 0		62: 0		63: 0		64: 0		65: 0		66: 129033		67: 0		68: 0		69: 0
70: 0		71: 0		72: 0		73: 0		74: 0		75: 0		76: 96774		77: 0		78: 0		79: 0
80: 0		81: 0		82: 0		83: 0		84: 0		85: 0		86: 96774		87: 0		88: 0		89: 0
90: 0		91: 0		92: 0		93: 0		94: 0		95: 0		96: 96775		97: 0		98: 0		99: 0
</code></pre>
<p>Wieso ist das so?</p>
</blockquote>
<p>Haste die std::uniform_int_distribution lange leben lassen oder für jede Zahl eine neue genaut, wie es so oft hier im Form vorgeschlagen wird?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2408707</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2408707</guid><dc:creator><![CDATA[volkard]]></dc:creator><pubDate>Tue, 15 Jul 2014 11:25:29 GMT</pubDate></item><item><title><![CDATA[Reply to C++11-PRNGs on Tue, 15 Jul 2014 18:23:42 GMT]]></title><description><![CDATA[<p>Darf die <code>std::uniform_int_distribution</code> denn lügen wenn man dauernt neue Instanzen erzeugt?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2408791</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2408791</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Tue, 15 Jul 2014 18:23:42 GMT</pubDate></item><item><title><![CDATA[Reply to C++11-PRNGs on Tue, 15 Jul 2014 18:31:15 GMT]]></title><description><![CDATA[<p>Wieso lügen?<br />
Woher soll denn die nächste Instanz den Zustand ihrer Vorgängerin kennen?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2408792</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2408792</guid><dc:creator><![CDATA[Caligulaminus]]></dc:creator><pubDate>Tue, 15 Jul 2014 18:31:15 GMT</pubDate></item><item><title><![CDATA[Reply to C++11-PRNGs on Tue, 15 Jul 2014 18:57:21 GMT]]></title><description><![CDATA[<p>hustbaer schrieb:</p>
<blockquote>
<p>Darf die <code>std::uniform_int_distribution</code> denn lügen wenn man dauernt neue Instanzen erzeugt?</p>
</blockquote>
<p>So Sachen wie &quot;Produces random integer values i, uniformly distributed on the closed interval [a, b]&quot; habe ich immer nur so verstanden, daß daß die Ausgabefolge eines Objekts auf lange Sicht gleichverteilt ist. Keine Aussage drüber, was kurzfristig passiert.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2408798</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2408798</guid><dc:creator><![CDATA[volkard]]></dc:creator><pubDate>Tue, 15 Jul 2014 18:57:21 GMT</pubDate></item><item><title><![CDATA[Reply to C++11-PRNGs on Tue, 15 Jul 2014 19:22:51 GMT]]></title><description><![CDATA[<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/25894">@Caligulaminus</a><br />
Ich würde mal behaupten dass man <code>std::uniform_int_distribution</code> wunderbar stateless implementieren kann.</p>
<p>Bei anderen Verteilungen mag das schwieriger sein, keine Ahnung.<br />
Wobei ich mir grad schwer tue mir vorzustellen wo eine &quot;stateful&quot; Implementierung Sinn machen würde.</p>
<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/106">@volkard</a><br />
Ja klar auf lange Sicht. Die Frage ist nur ob man &quot;stateful&quot; Distributions erlauben sollte.<br />
Vorberechnete Konstanten/Lookup-Tables/... sind klarerweise OK. Mutable State in einer Distribution ... weiss nicht ob das so gut ist.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2408799</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2408799</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Tue, 15 Jul 2014 19:22:51 GMT</pubDate></item><item><title><![CDATA[Reply to C++11-PRNGs on Tue, 15 Jul 2014 19:30:40 GMT]]></title><description><![CDATA[<p>hustbaer schrieb:</p>
<blockquote>
<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/25894">@Caligulaminus</a><br />
Ich würde mal behaupten dass man <code>std::uniform_int_distribution</code> wunderbar stateless implementieren kann.</p>
</blockquote>
<p>Das denke ich auch, aber erstens ist stateful sicher effizienter und zweitens ist die std::uniform_int_distribution nunmal stateful implementiert (zumindest bei meinem MSVC).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2408801</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2408801</guid><dc:creator><![CDATA[Caligulaminus]]></dc:creator><pubDate>Tue, 15 Jul 2014 19:30:40 GMT</pubDate></item><item><title><![CDATA[Reply to C++11-PRNGs on Tue, 15 Jul 2014 20:58:35 GMT]]></title><description><![CDATA[<p>volkard schrieb:</p>
<blockquote>
<p>hustbaer schrieb:</p>
<blockquote>
<p>Darf die <code>std::uniform_int_distribution</code> denn lügen wenn man dauernt neue Instanzen erzeugt?</p>
</blockquote>
<p>So Sachen wie &quot;Produces random integer values i, uniformly distributed on the closed interval [a, b]&quot; habe ich immer nur so verstanden, daß daß die Ausgabefolge eines Objekts auf lange Sicht gleichverteilt ist. Keine Aussage drüber, was kurzfristig passiert.</p>
</blockquote>
<p>Die einzigen Member von uniform_int_distribution beim GCC sind min und max, das Ziehen könnte hier theoretisch const sein.</p>
<p>Allerdings ist das nicht bei jeder Distribution so, std::normal_distribution hat einen State.</p>
<p>Die Verteilheit sollte aber auch gewährleistet sein, wenn man jedesmal eine neue uniform_int_distribution erstellt, nur halt vielleicht etwas langsamer.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2408821</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2408821</guid><dc:creator><![CDATA[bits&#x2F;random.h]]></dc:creator><pubDate>Tue, 15 Jul 2014 20:58:35 GMT</pubDate></item><item><title><![CDATA[Reply to C++11-PRNGs on Tue, 15 Jul 2014 21:03:45 GMT]]></title><description><![CDATA[<p>Caligulaminus schrieb:</p>
<blockquote>
<p>stateful implementiert (zumindest bei meinem MSVC).</p>
</blockquote>
<p>Also bei mir nicht wirklich, wenn ich da mal kurz drüber schaue finde ich nur min/max, und wenn ich die distribution jedes mal neu erstelle bekomme ich auch immer noch exakt die selben Ergebnisse.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2408824</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2408824</guid><dc:creator><![CDATA[cooky451]]></dc:creator><pubDate>Tue, 15 Jul 2014 21:03:45 GMT</pubDate></item><item><title><![CDATA[Reply to C++11-PRNGs on Tue, 15 Jul 2014 22:36:44 GMT]]></title><description><![CDATA[<p>cooky451 schrieb:</p>
<blockquote>
<p>Also bei mir nicht wirklich</p>
</blockquote>
<p>Ich glaube, ich muß mich korrigieren, meine std::uniform_int_distribution scheint doch nicht stateful zu sein.<br />
Morgen muß ich noch mal genauer schauen...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2408842</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2408842</guid><dc:creator><![CDATA[Caligulaminus]]></dc:creator><pubDate>Tue, 15 Jul 2014 22:36:44 GMT</pubDate></item><item><title><![CDATA[Reply to C++11-PRNGs on Wed, 16 Jul 2014 06:52:05 GMT]]></title><description><![CDATA[<p>volkard schrieb:</p>
<blockquote>
<p>Haste die std::uniform_int_distribution lange leben lassen oder für jede Zahl eine neue genaut, wie es so oft hier im Form vorgeschlagen wird?</p>
</blockquote>
<p>Ich hab eine Distribution für alle Werte genommen. Ehrlich gesagt habe ich nie Diesbezügliches im Forum gelesen.</p>
<p>Also bei meinem Visual C++ 2013 Express ist <code>std::uniform_int_distribution</code> auch zustandslos implementiert.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2408865</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2408865</guid><dc:creator><![CDATA[Fytch]]></dc:creator><pubDate>Wed, 16 Jul 2014 06:52:05 GMT</pubDate></item><item><title><![CDATA[Reply to C++11-PRNGs on Thu, 17 Jul 2014 13:42:59 GMT]]></title><description><![CDATA[<p>Mal außen vor, dass der Generator keine vereinfachte std::shuffle_order_engine und natürlich nicht gleichverteilt ist (wie hoch ist die Wahrscheinlichkeit, mit ihm dreimal hintereinander die gleiche Zahl zu ziehen?) und eine uniform_int_distribution keinerlei Verpflichtung hat, damit sinnvoll klarzukommen -- irgendwie sieht mir das Ergebnis so aus, als sei eine PermutationEngine&lt;10&gt; als Generator für eine uniform_int_distribution(0, 100) verwendet worden. Das könnte natürlich nicht gutgehen.</p>
<p>@asfdlol: Zeig doch mal den kompletten Code, der das Verhalten erzeugt.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2409127</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2409127</guid><dc:creator><![CDATA[seldon]]></dc:creator><pubDate>Thu, 17 Jul 2014 13:42:59 GMT</pubDate></item><item><title><![CDATA[Reply to C++11-PRNGs on Thu, 17 Jul 2014 22:36:29 GMT]]></title><description><![CDATA[<p>seldon schrieb:</p>
<blockquote>
<p>Mal außen vor, dass der Generator keine vereinfachte std::shuffle_order_engine und natürlich nicht gleichverteilt ist (wie hoch ist die Wahrscheinlichkeit, mit ihm dreimal hintereinander die gleiche Zahl zu ziehen?)</p>
</blockquote>
<p>Es sind keine guten Zufallszahlen wenn man nicht 3x hintereinander die selbe Zahl ziehen kann. Aber inwiefern soll das die (1 dimensionale) Gleichverteilung stören? Die ist ja gerade perfekt bei dem Generator.</p>
<blockquote>
<p>und eine uniform_int_distribution keinerlei Verpflichtung hat, damit sinnvoll klarzukommen -- irgendwie sieht mir das Ergebnis so aus, als sei eine PermutationEngine&lt;10&gt; als Generator für eine uniform_int_distribution(0, 100) verwendet worden. Das könnte natürlich nicht gutgehen.</p>
</blockquote>
<p>Keine Ahnung, ist das so?<br />
Was sind denn die Anforderungen die eine Distribution an den übergebenen Generator stellen darf?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2409180</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2409180</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Thu, 17 Jul 2014 22:36:29 GMT</pubDate></item><item><title><![CDATA[Reply to C++11-PRNGs on Thu, 17 Jul 2014 22:56:45 GMT]]></title><description><![CDATA[<p>hustbaer schrieb:</p>
<blockquote>
<p>Was sind denn die Anforderungen die eine Distribution an den übergebenen Generator stellen darf?</p>
</blockquote>
<blockquote>
<p>26.5.1.3 Uniform random number generator requirements</p>
<p>A uniform random number generator g of type G is a function object returning unsigned integer values such<br />
that each value in the range of possible results has (ideally) equal probability of being returned. [ Note: The<br />
degree to which g’s results approximate the ideal is often determined statistically. — end note ]</p>
</blockquote>
<p>Die Anforderungen werden hier also tatsächlich erfüllt. Es gibt, wie du schon anmerkst, keinen mathematischen Grund es anders zu verlangen. Die Zufallszahlen sind zwar schlecht (sowohl vor als auch nach dem man sie durch die Verteilungsfunktion gejagt hat), aber ihre Verteilung sollte richtig sein.</p>
<p>P.S.: Die Distributionen verlangen dann auch einen eben solchen uniform random number generator (§ 26.5.1.6, 2f). Nur um das nochmal klar zu stellen, falls es nicht offensichtlich war.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2409183</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2409183</guid><dc:creator><![CDATA[SeppJ]]></dc:creator><pubDate>Thu, 17 Jul 2014 22:56:45 GMT</pubDate></item><item><title><![CDATA[Reply to C++11-PRNGs on Thu, 17 Jul 2014 22:58:00 GMT]]></title><description><![CDATA[<p>Danke <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /></p>
<p>Und was sind die Anforderungen an min/max?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2409184</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2409184</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Thu, 17 Jul 2014 22:58:00 GMT</pubDate></item><item><title><![CDATA[Reply to C++11-PRNGs on Fri, 18 Jul 2014 00:02:00 GMT]]></title><description><![CDATA[<p>hustbaer schrieb:</p>
<blockquote>
<p>Und was sind die Anforderungen an min/max?</p>
</blockquote>
<p>min &lt; max <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f603.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--grinning_face_with_big_eyes"
      title=":D"
      alt="😃"
    /></p>
<p>Zumindest beim GCC klappt das auch wie man erwartet, d.h. es wird gewartet, bis genügend Information gesammelt wurde:</p>
<pre><code>#include &lt;random&gt;
#include &lt;iostream&gt;
#include &lt;functional&gt;
#include &lt;map&gt;

struct poor_mans_device
{
  std::mt19937 gen; 
  std::uniform_int_distribution&lt;int&gt; dis = std::uniform_int_distribution&lt;int&gt;(1, 6);
  typedef int result_type;
  static constexpr result_type min() {return 1;}
  static constexpr result_type max() {return 6;}
  result_type operator()() { return dis(gen); }
};

int main()
{
  poor_mans_device gen;
  std::uniform_int_distribution&lt;&gt; dis(10, 36);
  std::map&lt;int, int&gt; map;

  for (int n=0; n&lt;1000000; ++n)
    ++map[dis(gen)];
  for(int i = 10; i &lt; 37; ++i)
    std::cout &lt;&lt; i &lt;&lt; ' ' &lt;&lt; map[i] &lt;&lt; '\n';
}
</code></pre>
<p>Sollte Gleichverteilung ergeben.</p>
<p>Oder, um es noch extremer zu machen:</p>
<pre><code>#include &lt;random&gt;
#include &lt;iostream&gt;
#include &lt;functional&gt;
#include &lt;map&gt;

struct poor_mans_device
{
  int min_, max_;
  std::mt19937 gen; 
  std::uniform_int_distribution&lt;int&gt; dis;
   typedef int result_type;
  result_type min() const {return min_;}
  result_type max() const {return max_;}
  result_type operator()() { return dis(gen); }
  poor_mans_device(int min, int max): min_(min), max_(max), dis(min_, max_) {}
};

int main()
{
  poor_mans_device poor(0,1);
  poor_mans_device intermediate(0,1000);
  poor_mans_device good(0,1000000);

  std::uniform_int_distribution&lt;&gt; dis(10, 36);
  std::map&lt;int, int&gt; map_poor, map_intermediate, map_good, map_mixed;

  for (int n=0; n&lt;1000000; ++n)
    {
      for(int i = 1; i &lt; 3; ++i)
        {
          ++map_poor[dis(poor)];
          ++map_intermediate[dis(intermediate)];
          ++map_good[dis(good)];
        }
      ++map_mixed[dis(poor)];
      ++map_mixed[dis(intermediate)];
      ++map_mixed[dis(good)];
    }

  for(int i = 10; i &lt; 37; ++i)
    std::cout &lt;&lt; i &lt;&lt; '\t' &lt;&lt; map_poor[i] &lt;&lt; '\t'
              &lt;&lt; map_intermediate[i] &lt;&lt; '\t' 
              &lt;&lt; map_good[i] &lt;&lt; '\t'
              &lt;&lt; map_mixed[i] &lt;&lt; '\n';
}
</code></pre>
<p>Die Distribution muss also dynamisch mit sich ändernden Generatoren auskommen.</p>
<p>P.S.: Ein bisschen Overengineered ist das schon :p . Wenn Geschwindigkeit eine kritische Rolle spielen würde, würde ich mir den Einsatz nochmal überlegen. Da ist mindestens eine Abfrage drin, ob min und max vom Generator ausreichen oder ob mehrere Ziehungen nötig sind, die man in 99.9% aller Fälle nicht braucht und die immer die gleiche Antwort hat.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2409187</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2409187</guid><dc:creator><![CDATA[SeppJ]]></dc:creator><pubDate>Fri, 18 Jul 2014 00:02:00 GMT</pubDate></item><item><title><![CDATA[Reply to C++11-PRNGs on Fri, 18 Jul 2014 06:53:30 GMT]]></title><description><![CDATA[<p>seldon schrieb:</p>
<blockquote>
<p>@asfdlol: Zeig doch mal den kompletten Code, der das Verhalten erzeugt.</p>
</blockquote>
<p>Den habe ich leider nicht mehr (es erschliesst sich jedoch alles aus dem OP bis auf den Bereich vom Generator). Ich habe es auch nicht hinbekommen es zu reproduzieren, sondern bekomme stattdessen Verteilungen wie sie auch cooky451 etwa erhalten hat. Wie gesagt, vielleicht hatte ich irgendwo einen kleinen Fehler drin</p>
<p>seldon schrieb:</p>
<blockquote>
<p>Mal außen vor, dass der Generator keine vereinfachte std::shuffle_order_engine</p>
</blockquote>
<p>Sicher? Meine Engine nimmt doch immer einen <code>Range</code> -grossen Block von einer hypothetischen Engine, die konsequtive Werte modulo <code>Range</code> liefert, und gibt diese durchgemischt wieder.</p>
<p>seldon schrieb:</p>
<blockquote>
<p>natürlich nicht gleichverteilt ist (wie hoch ist die Wahrscheinlichkeit, mit ihm dreimal hintereinander die gleiche Zahl zu ziehen?)</p>
</blockquote>
<p>Der von dir genannte Fall ist kein Kriterium für Gleichverteilung. Für meinen Generator gilt die Laplace-Formel, womit er gleichverteilt ist.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2409199</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2409199</guid><dc:creator><![CDATA[Fytch]]></dc:creator><pubDate>Fri, 18 Jul 2014 06:53:30 GMT</pubDate></item></channel></rss>