<?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[Zufallszahlen zur Compile-Zeit]]></title><description><![CDATA[<p>Wie <a href="http://www.c-plusplus.net/forum/p2402798#2402798" rel="nofollow">hier</a> &quot;angekündigt&quot; möchte ich VTMPL ein wenig auf Vordermann bringen, und atm versuche ich gerade einen Compile-Zeit PRNG einzubauen.</p>
<p>Im Moment sieht das ganze so aus:</p>
<pre><code>template&lt; std::uintmax_t c = 25214903917,
	          std::uintmax_t a = 11,
	          std::uintmax_t m = (1ull &lt;&lt; 48) &gt;
	constexpr std::uintmax_t rand48( std::uintmax_t state = time() )
	{
		return (state * c + a) % m;
	}
</code></pre>
<p>Die Konstanten habe ich von <a href="http://rosettacode.org/wiki/Random_number_generator_%28included%29#POSIX_drand48.28.29" rel="nofollow">POSIX' <code>drand48</code> </a>.</p>
<p>Wobei <code>time()</code> so definiert ist:</p>
<pre><code>template&lt; typename format = VTMPL_STRING(&quot;SsMmHh&quot;) &gt;
	constexpr std::uintmax_t time()
	{
		using str = VTMPL_STRING( __TIME__ );

		constexpr auto Hh = parse_unsigned&lt;str&gt;().first;
		constexpr auto Mm = parse_unsigned&lt;str&gt;(3).first;
		constexpr auto Ss = parse_unsigned&lt;str&gt;(6).first;

		std::uintmax_t rval = 0;

		for( auto c : format::array )
		{
			rval *= 10;
			switch(c)
			{
				case 'H': rval += Hh / 10; break;
				case 'h': rval += Hh % 10; break;
				case 'M': rval += Mm / 10; break;
				case 'm': rval += Mm % 10; break;
				case 'S': rval += Ss / 10; break;
				case 's': rval += Ss % 10; break;

				default:
					VTMPL_ASSERT(0, &quot;Invalid time format string!&quot;);
			}
		}

		return rval;
	}
</code></pre>
<p>Das kann ich so natürlich nicht stehen lassen. Vor allem, weil zum Beispiel der LSB bei linearen Kongruenzgeneratoren bekanntlich dazu neigt, wenig Zufall zu zeigen und ich evt. einen Shift machen muss, um an die high-order Bits zu kommen. Allerdings soll die Qualität der Zufallszahlen nicht leiden.</p>
<p>Hat jemand eine Idee was für ein PRNG sich hier gut eignen würde und implementierbar ist? Oder ob man die Zeit noch sinnvoller in einen String packen könnte, um den PRNG besser zu seeden?</p>
<p>Das Repo ist <a href="https://github.com/Arcoth/VTMPL" rel="nofollow"><strong>hier</strong></a>. (Benötigter Compiler für den C++14-Code ist Clang &gt;= 3.4, sonst sollte GCC 4.8 reichen).</p>
<p>Vielen Dank für Ideen im Voraus.</p>
<p>P.S.: Hat jemand auch zufällig noch eine bessere Assertion-Methode (mit Fehlermeldung) für constexpr-Funktionen? Momentan habe ich es so:</p>
<pre><code>#define VTMPL_ASSERT( B, MSG ) ( B? 0 : throw ::std::invalid_argument{MSG})
</code></pre>
<p>Ist allerdings nicht sehr hübsch - die Fehlermeldung kriegt man nur zu sehen, wenn man auf die zweite logische Zeile des Compiler-Outputs schaut (subexpression not valid in a constant expression).</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/326240/zufallszahlen-zur-compile-zeit</link><generator>RSS for Node</generator><lastBuildDate>Sat, 11 Jul 2026 05:20:53 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/326240.rss" rel="self" type="application/rss+xml"/><pubDate>Sun, 08 Jun 2014 10:38:22 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Zufallszahlen zur Compile-Zeit on Sun, 08 Jun 2014 17:00:57 GMT]]></title><description><![CDATA[<p>Wie <a href="http://www.c-plusplus.net/forum/p2402798#2402798" rel="nofollow">hier</a> &quot;angekündigt&quot; möchte ich VTMPL ein wenig auf Vordermann bringen, und atm versuche ich gerade einen Compile-Zeit PRNG einzubauen.</p>
<p>Im Moment sieht das ganze so aus:</p>
<pre><code>template&lt; std::uintmax_t c = 25214903917,
	          std::uintmax_t a = 11,
	          std::uintmax_t m = (1ull &lt;&lt; 48) &gt;
	constexpr std::uintmax_t rand48( std::uintmax_t state = time() )
	{
		return (state * c + a) % m;
	}
</code></pre>
<p>Die Konstanten habe ich von <a href="http://rosettacode.org/wiki/Random_number_generator_%28included%29#POSIX_drand48.28.29" rel="nofollow">POSIX' <code>drand48</code> </a>.</p>
<p>Wobei <code>time()</code> so definiert ist:</p>
<pre><code>template&lt; typename format = VTMPL_STRING(&quot;SsMmHh&quot;) &gt;
	constexpr std::uintmax_t time()
	{
		using str = VTMPL_STRING( __TIME__ );

		constexpr auto Hh = parse_unsigned&lt;str&gt;().first;
		constexpr auto Mm = parse_unsigned&lt;str&gt;(3).first;
		constexpr auto Ss = parse_unsigned&lt;str&gt;(6).first;

		std::uintmax_t rval = 0;

		for( auto c : format::array )
		{
			rval *= 10;
			switch(c)
			{
				case 'H': rval += Hh / 10; break;
				case 'h': rval += Hh % 10; break;
				case 'M': rval += Mm / 10; break;
				case 'm': rval += Mm % 10; break;
				case 'S': rval += Ss / 10; break;
				case 's': rval += Ss % 10; break;

				default:
					VTMPL_ASSERT(0, &quot;Invalid time format string!&quot;);
			}
		}

		return rval;
	}
</code></pre>
<p>Das kann ich so natürlich nicht stehen lassen. Vor allem, weil zum Beispiel der LSB bei linearen Kongruenzgeneratoren bekanntlich dazu neigt, wenig Zufall zu zeigen und ich evt. einen Shift machen muss, um an die high-order Bits zu kommen. Allerdings soll die Qualität der Zufallszahlen nicht leiden.</p>
<p>Hat jemand eine Idee was für ein PRNG sich hier gut eignen würde und implementierbar ist? Oder ob man die Zeit noch sinnvoller in einen String packen könnte, um den PRNG besser zu seeden?</p>
<p>Das Repo ist <a href="https://github.com/Arcoth/VTMPL" rel="nofollow"><strong>hier</strong></a>. (Benötigter Compiler für den C++14-Code ist Clang &gt;= 3.4, sonst sollte GCC 4.8 reichen).</p>
<p>Vielen Dank für Ideen im Voraus.</p>
<p>P.S.: Hat jemand auch zufällig noch eine bessere Assertion-Methode (mit Fehlermeldung) für constexpr-Funktionen? Momentan habe ich es so:</p>
<pre><code>#define VTMPL_ASSERT( B, MSG ) ( B? 0 : throw ::std::invalid_argument{MSG})
</code></pre>
<p>Ist allerdings nicht sehr hübsch - die Fehlermeldung kriegt man nur zu sehen, wenn man auf die zweite logische Zeile des Compiler-Outputs schaut (subexpression not valid in a constant expression).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2402957</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2402957</guid><dc:creator><![CDATA[Columbo]]></dc:creator><pubDate>Sun, 08 Jun 2014 17:00:57 GMT</pubDate></item><item><title><![CDATA[Reply to Zufallszahlen zur Compile-Zeit on Sun, 08 Jun 2014 11:04:44 GMT]]></title><description><![CDATA[<p>Multiply With Carry ist super.</p>
<p>volkard hat mir mal eine <a href="http://www.c-plusplus.net/forum/p2029012#2029012" rel="nofollow">Implementierung</a> vorgeschlagen, die ich nun auch schon einige Zeit verwende. Vergiss nicht, ihn zu erwähnen <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>
]]></description><link>https://www.c-plusplus.net/forum/post/2402963</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2402963</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Sun, 08 Jun 2014 11:04:44 GMT</pubDate></item><item><title><![CDATA[Reply to Zufallszahlen zur Compile-Zeit on Sun, 08 Jun 2014 12:14:35 GMT]]></title><description><![CDATA[<p>War klar dass die Lösung dazu von Volkard kommt. <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>Gut, kleiner Test:</p>
<pre><code>#include &quot;index_list.hxx&quot;
#include &quot;algorithms.hxx&quot;
#include &quot;time.hxx&quot;

#include &lt;iterator&gt;
#include &lt;iostream&gt;

template&lt; std::uintmax_t a,
          std::uintmax_t mask,
          int shift &gt;
constexpr std::uintmax_t rand_impl( std::uintmax_t x )
{
	return a*(x&amp;mask)+(x&gt;&gt;shift);
}

template&lt; std::uintmax_t a = 4294967118,
          std::uintmax_t mask = 0xffffffff,
          int shift = 32 &gt;
constexpr std::uintmax_t rand( std::uintmax_t x )
{
	return rand_impl&lt;a, mask, shift&gt;(x? x : 1);
}

int main()
{

	using namespace vtmpl;
	using namespace functions;

	copy&lt; sub_list&lt;eval&lt;generate_recursive&lt;10, chain&lt; from_function_ptr&lt;std::uintmax_t, &amp;rand&gt;::function,
	                                                  modulo           &lt;std::uintmax_t, 10   &gt;::function &gt;::function,
	                                       value_list&lt;std::uintmax_t, time&lt;VTMPL_STRING(&quot;HhMmSs&quot;)&gt;()&gt; &gt;&gt;, 1&gt; &gt;( std::ostream_iterator&lt;std::uintmax_t&gt;{std::cout, &quot; &quot;} );
}
</code></pre>
<p>Ausgabe:</p>
<pre><code>6 8 4 2 6 8 4 2 6 8
</code></pre>
<pre><code>2 6 8 4 2 6 8 4 2 6
</code></pre>
<pre><code>8 4 2 6 8 4 2 6 8 4
</code></pre>
<p>Und zwar immer sowas. Nichts ungerades. Worauf genau ist das zurückzuführen?</p>
<p>Nexus schrieb:</p>
<blockquote>
<p>Vergiss nicht, ihn zu erwähnen <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>
</blockquote>
<p>Auf keinen Fall. <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>
]]></description><link>https://www.c-plusplus.net/forum/post/2402973</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2402973</guid><dc:creator><![CDATA[Columbo]]></dc:creator><pubDate>Sun, 08 Jun 2014 12:14:35 GMT</pubDate></item><item><title><![CDATA[Reply to Zufallszahlen zur Compile-Zeit on Sun, 08 Jun 2014 15:45:41 GMT]]></title><description><![CDATA[<p>Zur Laufzeit hat er noch ungerade Zahlen dabei.<br />
<a href="https://ideone.com/1LSSJi" rel="nofollow">https://ideone.com/1LSSJi</a></p>
<p>Deine Zahlen sind viel schlimmer als nur gerade Zahlen, sie sind immer<br />
6 8 4 2<br />
Rückwärts gelesen ist 2 4 8 6 2 4 8 6 2 4 8 6… die Folge der Endziffern der Zweierpotenzen. Ob das was zu bedeuten hat? Wie sehen die Zahlen aus, wenn Du %10 wegläßt?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2402997</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2402997</guid><dc:creator><![CDATA[volkard]]></dc:creator><pubDate>Sun, 08 Jun 2014 15:45:41 GMT</pubDate></item><item><title><![CDATA[Reply to Zufallszahlen zur Compile-Zeit on Sun, 08 Jun 2014 15:53:06 GMT]]></title><description><![CDATA[<pre><code>a * ( x &amp; mask) + ( x &gt;&gt; shift )
</code></pre>
<p>Damit immer gerade Zahlen herauskommen muss das LSB von <code>a*(x&amp;mask)</code> und das LSB von <code>(x &gt;&gt; shift)</code> immer den gleichen Wert haben.</p>
<p>Weil <code>a</code> gerade ist, wird das Produkt immer LSB = 0 haben. Also muss auch der LSB von <code>(x &gt;&gt; shift)</code> immer 0 sein.</p>
<p>Der LSB von <code>(x &gt;&gt; shift)</code> ist genau dann 0, wenn das dreiunddreißigste Bit von <code>x</code> 0 ist.</p>
<p>Hmm.</p>
<blockquote>
<p>Wie sehen die Zahlen aus, wenn Du %10 wegläßt?</p>
</blockquote>
<p>Hier mal hundert Zahlen ohne Modulo:</p>
<pre><code>165202
709537157827836
18320445695112183321
4034941536540204777
1077097940759904241
15225684482536352076
2576526502479054982
17772549771398888455
11902516376801053436
2053371950223890525
15337175421055998526
2154156764651346093
832137497223852512
1607628732448582373
9822116068662156950
5711582885095073338
7731244528034613771
13055805085336791625
8087596297962693323
12309642165996468437
12133744546030689850
10772080149562307596
13164782081298722170
10177269947472123065
9391575733387363446
17130430542210366034
3887585238828742349
7669760471293026211
3729226229867673389
7950250686240588341
8983838887856664070
13693596548621828530
6493770048280412094
1500613125441597272
16085783357756691583
15923131680788672110
4120070485795113834
1973574268267953811
3311973609001421089
2738057760586933633
13999761573072303444
1090844496442265746
4296874298402729926
11010438367382001852
18240378989381303459
10849800677655621302
5437162524039496111
2265523477304705748
8002336366320077361
16695628390350023796
6106155666080882920
18157775071069866729
2202272126584867383
13534946032276304022
9505251887306604904
253751229389567467
1231019674374341632
2493168901221232095
168794677923978970
9341202849163721289
16088328664470525885
4863913500242917444
17308661153883748422
4528360746232977137
4470410620244853897
2005232638480019332
16473867154908871341
2689065228355216027
17435582547020114637
16654991114482835304
4326093641935098845
2926798527455530901
18311511721806413350
8551277775264962680
8817019079483636324
7095062909634395803
274366190526542426
13598110923525962756
14780738618014398222
2064186824126034874
16290350107687649190
16967310510173401520
2928238697297965731
12249635048885943358
17655653791039426320
5489622808781455988
18180189215825025587
16042764812072536654
3366522284540931933
7097584058358586244
12821848231883312464
12204769124595210600
17088654540169831050
14136906993251816655
9476299793277184532
6009184927601906316
9752494614049490050
4059014692097732554
6670868479662639591
15682740410497125611
601315101185592810
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2403000</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2403000</guid><dc:creator><![CDATA[Columbo]]></dc:creator><pubDate>Sun, 08 Jun 2014 15:53:06 GMT</pubDate></item><item><title><![CDATA[Reply to Zufallszahlen zur Compile-Zeit on Sun, 08 Jun 2014 16:03:08 GMT]]></title><description><![CDATA[<p>Das sind jetzt total andere Zahlen, finde ich. Auch ungerade und so.<br />
edit: Drei kurze Folgen mit %100 wären auch spannend.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2403001</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2403001</guid><dc:creator><![CDATA[volkard]]></dc:creator><pubDate>Sun, 08 Jun 2014 16:03:08 GMT</pubDate></item><item><title><![CDATA[Reply to Zufallszahlen zur Compile-Zeit on Sun, 08 Jun 2014 16:22:08 GMT]]></title><description><![CDATA[<p>Total irre.</p>
<pre><code>171903 // seed
54
72
96
28
4
72
96
28
4
...
</code></pre>
<pre><code>171948
64
52
36
48
64
52
36
48
...
</code></pre>
<pre><code>172016
88
84
12
16
88
84
12
...
</code></pre>
<p>Aber wenn ich den Modulo auf 2^64-1 setze:</p>
<pre><code>172115
739228265514570
18315160677943951582
4975704283593141053
18083477040222744644
14296870234884856646
444408591854352655
8979114121631575764
7028762842301311312
12237873217963521264
</code></pre>
<p>Kannste das erklären? Oder ich muss die Antwort bei Gott suchen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2403002</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2403002</guid><dc:creator><![CDATA[Columbo]]></dc:creator><pubDate>Sun, 08 Jun 2014 16:22:08 GMT</pubDate></item><item><title><![CDATA[Reply to Zufallszahlen zur Compile-Zeit on Sun, 08 Jun 2014 16:24:53 GMT]]></title><description><![CDATA[<p>Selbes Verhalten beim GCC 4.9 übrigens, wenn ich time.hxx nicht einbinde und einfach direkt <code>172014</code> hinschreibe.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2403003</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2403003</guid><dc:creator><![CDATA[Columbo]]></dc:creator><pubDate>Sun, 08 Jun 2014 16:24:53 GMT</pubDate></item><item><title><![CDATA[Reply to Zufallszahlen zur Compile-Zeit on Sun, 08 Jun 2014 16:46:33 GMT]]></title><description><![CDATA[<p>Ouch, ich habe den Fehler gefunden. Und es ist kein Fehler der Lib, sondern meiner. Es wird nicht Modulo 10 ausgegeben, sondern auch gespeichert. Also bekommt der Algo 6, 4, usw. als input. Hätte ich sehen sollen.</p>
<p>Edit: Der Code funktioniert natürlich:</p>
<pre><code>#include &quot;index_list.hxx&quot;
#include &quot;time.hxx&quot;
#include &quot;algorithms.hxx&quot;

#include &lt;iterator&gt;
#include &lt;iostream&gt;

template&lt; std::uintmax_t a,
          std::uintmax_t mask,
          int shift &gt;
constexpr std::uintmax_t rand_impl( std::uintmax_t x )
{
	return a*(x&amp;mask)+(x&gt;&gt;shift);
}

template&lt; std::uintmax_t a = 4294967118,
          std::uintmax_t mask = 0xffffffff,
          int shift = 32 &gt;
constexpr std::uintmax_t rand( std::uintmax_t x )
{
	return rand_impl&lt;a, mask, shift&gt;(x? x : 1);
}

int main()
{

    using namespace vtmpl;
    using namespace functions;

    using list = generate_recursive&lt;20, from_function_ptr&lt;std::uintmax_t, &amp;rand&gt;,
                                    value_list&lt;std::uintmax_t, time()&gt; &gt;;

    copy&lt; transform&lt;eval&lt;list&gt;, modulo&lt;std::uintmax_t, 10&gt;&gt; &gt;( std::ostream_iterator&lt;std::uintmax_t&gt;{std::cout, &quot;\n&quot;} );
}
</code></pre>
<p>Ausgabe wie erwartet</p>
<pre><code>7 6 6 7 7 5 1 5 1 9 5 9 5 4 6 2 5 1 6 6 9
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2403006</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2403006</guid><dc:creator><![CDATA[Columbo]]></dc:creator><pubDate>Sun, 08 Jun 2014 16:46:33 GMT</pubDate></item></channel></rss>