<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.3.4">Jekyll</generator><link href="http://localhost:4000/feed.xml" rel="self" type="application/atom+xml" /><link href="http://localhost:4000/" rel="alternate" type="text/html" /><updated>2026-03-17T22:06:55+01:00</updated><id>http://localhost:4000/feed.xml</id><title type="html">jonathan-dumke.de</title><subtitle>Eine Webseite über vieles was mich interessiert oder anficht.</subtitle><entry><title type="html">Ist das LSB gesetzt?</title><link href="http://localhost:4000/programmierung/2026/03/02/ist-das-lsb-gesetzt.html" rel="alternate" type="text/html" title="Ist das LSB gesetzt?" /><published>2026-03-02T00:00:00+01:00</published><updated>2026-03-02T00:00:00+01:00</updated><id>http://localhost:4000/programmierung/2026/03/02/ist-das-lsb-gesetzt</id><content type="html" xml:base="http://localhost:4000/programmierung/2026/03/02/ist-das-lsb-gesetzt.html"><![CDATA[<h2 id="einleitung">Einleitung</h2>
<p>Im letzten Beitrag haben wir uns mit dem MSB bzw wertniedrigsten Bit beschäftigt, hier soll es um seinen Konterpart, das LSB oder werthöchste Bit gehen. 
Je nachdem ob wir einen Typ mit oder ohne Vorzeichen verwenden zeigt uns dieses Bit das Vorzeichen an bzw teilt uns mit das der Wert sehr gross, in Bezug zum Datentyp, ist.</p>
<h2 id="vorüberlegungen">Vorüberlegungen</h2>
<p>Im Gegensatz zum letzten Artikel ergibt sich ein Problem: Durch die verschiedenen Bitbreiten der Typen liegt das interessante Bit immer woanders:</p>

<table style="font-family:monospace; padding:0.25em">
<tr>
<th> Typen </th><th> Bitposition</th>
</tr>
<tr>
<th> (u)byte </th><td style="text-align:right"> 7 </td>
</tr>
<tr>
<th> (u)short </th><td style="text-align:right"> 15 </td>
</tr>
<tr>
<th> (u)int  </th><td style="text-align:right"> 31 </td>
</tr>
<tr>
<th> (u)long </th><td style="text-align:right"> 63 </td> 
</tr>
</table>

<p>Angestrebt ist eine Lösung die für alle Datentypen gleichermassen funktioniert. Wie wir aus dem vorherigen Beitrag wissen, können wir mit der bitweisen Und-Verknüpfung prüfen, ob ein spezifisches Bit gesetzt ist oder eben nicht. Nachteilig auf den ersten Blick, wirken die variablen Positionen unseres Zielbits. Ein Wert muss sich zum anderen hin bewegen, dafür gibt gibt es die sogenannten Shift-Operatoren <code class="language-plaintext highlighter-rouge">&lt;&lt;</code> und <code class="language-plaintext highlighter-rouge">&gt;&gt;</code>, welchen den linken Operanden um die rechts gegebene Anzahl Bits in Richtung der Pfeilspitzen verschieben. Die Wirkung hängt in der ersten Linie davon ab, wie stark die verwendete Sprache von der Hardware abstrahiert, dazu an andere Stelle mehr. Das Referenzhandbuch für D<sup id="fnref:1"><a href="#fn:1" class="footnote" rel="footnote" role="doc-noteref">1</a></sup> cmacht keine Angaben dazu wie sich die Shiftoperatoren verhalte, das obliegt wohl dem verwendeten Compiler.</p>

<p>Um es kurz zu halten, eine Variable zu sparen und den finalen Ausdruck im <code class="language-plaintext highlighter-rouge">return</code>-Statement nicht zu zu sehr in die Länge zu ziehe, werden wir im Folgenden useren Prüfling nach rechts schieben, bis das original LSB an der Position 0 steht und wir wie gewohnt das MSB checken können.</p>

<h2 id="implementierung">Implementierung</h2>
<h3 id="was-wollen-wir-erhalten">Was wollen wir erhalten?</h3>
<p>Zuerst wieder die Frage nach den gewünschten Resultaten. Es soll ein <code class="language-plaintext highlighter-rouge">bool</code>zurückgegeben werden, welches mitteilt ob das LSB gesetzt ist, da wir die komplette Pallete an Integertypen abdecken wollen, ist das Template das Mittel der wahl, mehr dazu in Kürze:</p>

<figure class="highlight"><pre><code class="language-d" data-lang="d"><span class="k">unittest</span>
<span class="p">{</span>
	<span class="k">import</span> <span class="n">std</span><span class="p">.</span><span class="n">stdio</span><span class="p">:</span> <span class="n">writeln</span><span class="p">,</span> <span class="n">write</span><span class="p">;</span>
	<span class="n">writeln</span><span class="p">(</span><span class="s">"Testing lsbtest:"</span><span class="p">);</span>
	<span class="n">write</span><span class="p">(</span><span class="s">"byte:  14 (expecting: false): "</span><span class="p">);</span>
	<span class="k">assert</span><span class="p">(</span><span class="kc">false</span> <span class="p">==</span> <span class="n">LSBset</span><span class="p">!(</span><span class="kt">byte</span><span class="p">).</span><span class="n">check</span><span class="p">(</span><span class="mi">14</span><span class="p">));</span>
	<span class="n">write</span><span class="p">(</span><span class="s">"passed\n ubyte: 254 (expexting: true): "</span><span class="p">);</span>
	<span class="k">assert</span><span class="p">(</span><span class="kc">true</span> <span class="p">==</span> <span class="n">LSBset</span><span class="p">!(</span><span class="kt">ubyte</span><span class="p">).</span><span class="n">check</span><span class="p">(</span><span class="mi">254</span><span class="p">));</span>
	<span class="n">write</span><span class="p">(</span><span class="s">"passed\n int: -2 (expected: true): "</span><span class="p">);</span>
	<span class="k">assert</span><span class="p">(</span><span class="kc">true</span> <span class="p">==</span> <span class="n">LSBset</span><span class="p">!(</span><span class="kt">int</span><span class="p">).</span><span class="n">check</span><span class="p">(-</span><span class="mi">2</span><span class="p">));</span>
	<span class="n">write</span><span class="p">(</span><span class="s">"passed\n long: 2000000 (expected: false): "</span><span class="p">);</span>
	<span class="k">assert</span><span class="p">(</span><span class="kc">false</span> <span class="p">==</span> <span class="n">LSBset</span><span class="p">!(</span><span class="kt">long</span><span class="p">).</span><span class="n">check</span><span class="p">(</span><span class="mi">200000</span><span class="p">));</span>
	<span class="n">writeln</span><span class="p">(</span><span class="s">"passed"</span><span class="p">);</span>
	<span class="n">writeln</span><span class="p">(</span><span class="s">"All tests (4) passed."</span><span class="p">);</span> 
<span class="p">}</span></code></pre></figure>

<h3 id="das-template">Das Template</h3>
<p>Die angestrebte generische Lösungsvariante wird in D durch Templates<sup id="fnref:2"><a href="#fn:2" class="footnote" rel="footnote" role="doc-noteref">2</a></sup> realisiert. Grob gesagt handelt es dabei um Container für Funktionen und Variablen, die eine spezielle Syntax für Platzhalter zulassen, wo normalerweise ein wohldefinierter Typbezeicher stünde. 
Sollen jetzt Routinen mit einer Gruppe verwandter Datentypen, also solchen mit identischen Eigenschaften, arbeiten – wie hier mit Ganzzahltypen –, müssen wir jene nur schblonieren und, wie in den Unittests gezeigt, entsprechend initialiesieren. Im Falle unserer Überlegungen sähe, dass dann exemplarisch so aus:</p>

<figure class="highlight"><pre><code class="language-d" data-lang="d"><span class="k">template</span> <span class="n">LSBset</span><span class="p">(</span><span class="n">T</span><span class="p">)</span>
<span class="p">{</span>
	<span class="kt">bool</span> <span class="n">check</span><span class="p">(</span><span class="n">T</span> <span class="n">candidate</span><span class="p">)</span>
	<span class="p">{</span>
		<span class="n">candidate</span> <span class="p">=</span> <span class="n">candidate</span> <span class="p">&gt;&gt;</span> <span class="p">((</span><span class="n">T</span><span class="p">.</span><span class="n">sizeof</span><span class="p">*</span><span class="mi">8</span><span class="p">)</span> <span class="p">-</span><span class="mi">1</span><span class="p">);</span>
		<span class="k">return</span> <span class="p">(</span><span class="mi">1</span> <span class="p">==</span> <span class="p">(</span><span class="n">candidate</span> <span class="p">&amp;</span> <span class="mi">1</span><span class="p">));</span>
	<span class="p">}</span> 
<span class="p">}</span>
<span class="c1">// es folgen obenstehende Tests</span></code></pre></figure>

<p>Wie der Dokumentation zu entnehmen ist gibt es in D zwei Varianten Bits nach rechts (kleiner werdende Richtung) zu schieben.
a) unter Beibehaltung des Vorzeichens (<code class="language-plaintext highlighter-rouge">&gt;&gt;</code>)
b) ohne Beachtung des Vorzeichens (<code class="language-plaintext highlighter-rouge">&gt;&gt;&gt;</code>)</p>

<p>Da alle Ganzzahltypen unterstützt werden sollen, bleibt uns nur ersterer, ansonsten ernten wir Fehler während der Übersetzung. Gründe hierfür sind nicht unterstützte implizite Typumwandlungen (soganannte Casts) von Vorzeichen behafteten Typen (<code class="language-plaintext highlighter-rouge">byte</code> und <code class="language-plaintext highlighter-rouge">int</code>) in vorzeichenlose Typen.</p>

<p>Ebenfalls als neues Syntaxelement shen wir die  Eigenschaft<sup id="fnref:3"><a href="#fn:3" class="footnote" rel="footnote" role="doc-noteref">3</a></sup> <code class="language-plaintext highlighter-rouge">sizeof</code>, die jedem Datentyp – damit auch jeder Variablen – begegeben ist Anzahl der belegten Bytes liefert. Um die Grösse in Bit zu erhalten, multiplizieren wir mit acht. Damit das zu prüfende Bit nicht aus dem Speicher hinausgeschoben wird, subtrahieren wir eins, weil n — 1 Shiftings das LSB auf die Position des MSB bringen.</p>

<p>Zum Abschluss noch der MSB-Test, wie wir ihn bereits kennen.</p>

<p>Weiter oben sprach ich von kryptischen Ausdrücken, welche entstehen können, wenn man bestrebt alles in kompaktester Weise zu notieren. Als Beispiel bringe ich obige Variante als Einzeiler, die beim Debuggen keine Freude macht, wenn der compiler einen Fehler wirft:</p>

<figure class="highlight"><pre><code class="language-d" data-lang="d">	<span class="k">return</span> <span class="p">(</span><span class="mi">1</span>  <span class="p">==((</span><span class="n">candidate</span> <span class="p">&gt;&gt;</span> <span class="p">((</span><span class="n">candidate</span><span class="p">.</span><span class="n">sizeof</span><span class="p">*</span><span class="mi">8</span><span class="p">)</span> <span class="p">-</span><span class="mi">1</span><span class="p">))</span> <span class="p">&amp;</span> <span class="mi">1</span><span class="p">));</span></code></pre></figure>

<h2 id="fazit">Fazit</h2>
<p>Templating in der hier gezeigten Form ist sehr elegant, da man keine komplette Klasse konstruieren muss um generischen Code zu bauen, hier der funktional Identische Code in Pascal</p>

<figure class="highlight"><pre><code class="language-pascal" data-lang="pascal"><span class="cm">{$mode objfpc}</span>
<span class="k">program</span> <span class="n">lsbset</span><span class="p">;</span>
<span class="k">type</span>
	<span class="n">generic</span> <span class="n">TLsbSet</span><span class="p">&lt;</span><span class="n">_T</span><span class="p">&gt;</span> <span class="p">=</span> <span class="k">class</span><span class="p">(</span><span class="kt">TObject</span><span class="p">)</span>
	<span class="k">public</span>
		<span class="k">function</span> <span class="n">check</span><span class="p">(</span><span class="n">candidate</span> <span class="p">:</span> <span class="n">_T</span><span class="p">)</span> <span class="p">:</span> <span class="kt">boolean</span><span class="p">;</span>
	<span class="k">end</span><span class="p">;</span>
	
	<span class="n">TIsIntegerNegative</span> <span class="p">=</span> <span class="n">specialize</span> <span class="n">TLsbSet</span><span class="p">&lt;</span><span class="kt">integer</span><span class="p">&gt;;</span>
	
	
	<span class="k">function</span> <span class="n">TLsbSet</span><span class="p">.</span><span class="n">check</span><span class="p">(</span><span class="n">candidate</span><span class="p">:</span> <span class="n">_T</span><span class="p">)</span> <span class="p">:</span> <span class="kt">boolean</span><span class="p">;</span>
	<span class="k">begin</span>
		<span class="cm">{$ifdef ENDIAN_LITTLE}</span>
			<span class="n">candidate</span> <span class="p">:=</span> <span class="n">candidate</span> <span class="k">shr</span> <span class="p">((</span><span class="n">sizeOf</span><span class="p">(</span><span class="n">candidate</span><span class="p">)*</span><span class="m">8</span><span class="p">)-</span><span class="m">1</span><span class="p">);</span>
		<span class="cm">{$else}</span>
			<span class="n">candidate</span><span class="p">:</span> <span class="p">=</span> <span class="n">candidate</span> <span class="k">shl</span> <span class="p">((</span><span class="n">sizeOf</span><span class="p">(</span><span class="n">candidate</span><span class="p">)*</span><span class="m">8</span><span class="p">)-</span><span class="m">1</span><span class="p">);</span>
		<span class="cm">{$endif}</span>
		<span class="n">check</span> <span class="p">:=</span> <span class="p">(</span><span class="m">1</span> <span class="p">=</span> <span class="n">candidate</span> <span class="k">and</span> <span class="m">1</span><span class="p">);</span>
	<span class="k">end</span><span class="p">;</span>

	
<span class="k">var</span>
	<span class="n">negint</span> <span class="p">:</span> <span class="n">TIsIntegerNegative</span><span class="p">;</span>
	
<span class="k">Begin</span>
	
		<span class="n">negint</span> <span class="p">:=</span> <span class="n">TIsIntegerNegative</span><span class="p">.</span><span class="n">create</span><span class="p">;</span>
		
		<span class="k">writeln</span><span class="p">(</span><span class="s">'Is -12 negative: '</span><span class="p">,</span> <span class="n">negint</span><span class="p">.</span><span class="n">check</span><span class="p">(-</span><span class="m">12</span><span class="p">));</span>
		<span class="k">writeln</span><span class="p">(</span><span class="s">'Is 1024 negative: '</span><span class="p">,</span> <span class="n">negint</span><span class="p">.</span><span class="n">check</span><span class="p">(</span><span class="m">1024</span><span class="p">));</span>

<span class="k">End</span><span class="p">.</span></code></pre></figure>

<p>Zieht man das Hauptprogramm ab, weil ich in D den vom DMD bereitgestellten Default-Stub (Schalter <code class="language-plaintext highlighter-rouge">-main</code>) für den Testrunner nutze, erkennt der/die geneigte Lesende sehr deutlich den Code-Überhang, der durch das Definieren und Implemtieren der Klasse entsteht. Zusätzlich sieht man, dass der Code Rücksicht auf die Endianess der Zielarchitektur nemen muss, da auf Big-Endian-Systemen nach links zu schieben ist, D abstrahiert diesen Schritt für den Programmierer dankenswerter Weise.</p>

<p>Kehrseite der Medalie ist allerdings, dass man in D nicht auf triviale Weise in die oberen 32 Bit eines long-Wertes hineinschieben kann, da es bei Linksshifts eine Beschränkung auf höchstens 31 Schritte gibt. Das MSB zu setzen geht dann zwar, aber man kommt mit seiner 1 dann nicht auf konsitente Art zu Bit 63. Dies ist auch einer der Gründe, warum ich diese Variante hier nicht vorgestellt habe.</p>
<h2 id="referenzen">Referenzen</h2>
<div class="footnotes" role="doc-endnotes">
  <ol>
    <li id="fn:1">
      <p><a href="https://dlang.org/spec/expression.html#shift_expressions">https://dlang.org/spec/expression.html#shift_expressions</a> (zuletzt aufgerufen 2026/02/22) <a href="#fnref:1" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:2">
      <p><a href="https://dlang.org/spec/template.html">https://dlang.org/spec/template.html</a> (zuletzt aufgerufen 2026/02/24) <a href="#fnref:2" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:3">
      <p><a href="https://dlang.org/spec/property.html">https://dlang.org/spec/property.html</a> (zuletzt aufgerufen 2026/02/25) <a href="#fnref:3" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
  </ol>
</div>]]></content><author><name></name></author><category term="programmierung" /><category term="programmierung" /><category term="d" /><category term="d-lang" /><category term="integer" /><category term="ganzzahlen" /><category term="lsb" /><summary type="html"><![CDATA[Einleitung Im letzten Beitrag haben wir uns mit dem MSB bzw wertniedrigsten Bit beschäftigt, hier soll es um seinen Konterpart, das LSB oder werthöchste Bit gehen. Je nachdem ob wir einen Typ mit oder ohne Vorzeichen verwenden zeigt uns dieses Bit das Vorzeichen an bzw teilt uns mit das der Wert sehr gross, in Bezug zum Datentyp, ist. Vorüberlegungen Im Gegensatz zum letzten Artikel ergibt sich ein Problem: Durch die verschiedenen Bitbreiten der Typen liegt das interessante Bit immer woanders:]]></summary></entry><entry><title type="html">Ungerade oder nicht?</title><link href="http://localhost:4000/programmierung/2026/02/18/ungerade-oder-nicht.html" rel="alternate" type="text/html" title="Ungerade oder nicht?" /><published>2026-02-18T00:00:00+01:00</published><updated>2026-02-18T00:00:00+01:00</updated><id>http://localhost:4000/programmierung/2026/02/18/ungerade-oder-nicht</id><content type="html" xml:base="http://localhost:4000/programmierung/2026/02/18/ungerade-oder-nicht.html"><![CDATA[<h2 id="einleitung">Einleitung</h2>
<p>Wenn man von einer anderen Programmiersorache kommt – in meinem Fall Pascal — und sich an neue heran wagt, sucht man seine vertrauten Helfelein.</p>

<p>Ich hantiere gerne mit Ganzzahlen, um Beispielsweise Primzahllisten zu ereugen. Eine Hauptfrage die sich  in diesem Kontext stellt, ist ob ein Kandidat gerade oder ungerade ist.  In Pascal greift der findige Programmierer zum Funktion <code class="language-plaintext highlighter-rouge">odd()</code> aus der Unit <code class="language-plaintext highlighter-rouge">System</code>, welche die gewünschte Information in eine <code class="language-plaintext highlighter-rouge">boolean</code>-Wertes liefert. Die Sprache D kennt eine solche Hilfsroutine out of the Box nicht, zumindest hab ich die in der Standardbibliothek bislang nicht gefunden. Als kleine Fingerübung implentieren wir ein solche im Nachgang.</p>

<h2 id="vorüberlegungen">Vorüberlegungen</h2>
<p>Es gibt zwei Herangehensweisen an dieses Thema:
a) eine arithmetische, über den Modulo-Operator <code class="language-plaintext highlighter-rouge">a%b</code>
b) eine logische über bitweise Verknüpfungen.</p>

<p>Variante a) ist aus meiner Sicht langweilig, weil zu oft verwendet. Da die gängigen Prozessoren der x86/x64 keine Assembler-Instruktion für die Modulo-Rechnung haben, ist diese Variante von den Laufzeitkosten her recht teuer, da sie aus mehreren Opcodes zusammengebaut werden muss. 
Bei Variante b) ist nur zu Prüfen ob im Kandidaten das wertniederste  Bit – engl. most significant bit (MSB) – gesetzt ist, da dieses den Wert 1 repräsentiert. Dankenswerter Weise müssen wir hier keine besondere Rücksich auf die Speicherrepräsentation des Kandidaten nehmen. Der größte Vorteil liegt in der Tatsache, dass alle moderenen Prozessorfamilien bitweise Logikoperatoren in ihren Assemblern haben und in diesen sehr effizient sind.</p>

<h2 id="implementierung">Implementierung</h2>
<h3 id="was-wollen-wir-erhalten">Was wollen wir erhalten?</h3>
<p>Die Sprache D hat ein interessantes Feature, eingebaute Unittests<sup id="fnref:1"><a href="#fn:1" class="footnote" rel="footnote" role="doc-noteref">1</a></sup>, deshalb überlegen wir zuerst welche Ergebnisse wir erhalten wollen. Die Funktion soll ein <code class="language-plaintext highlighter-rouge">bool</code> liefern, derart dass sie <code class="language-plaintext highlighter-rouge">true</code> zurückgibt, wenn die Zahl ungerade ist, ansonsten <code class="language-plaintext highlighter-rouge">false</code>, die Tests sehen dann zum Beispiel so aus:</p>

<figure class="highlight"><pre><code class="language-d" data-lang="d"><span class="k">unittest</span>
<span class="p">{</span>
  <span class="k">import</span> <span class="n">std</span><span class="p">.</span><span class="n">stdio</span><span class="p">:</span> <span class="n">write</span><span class="p">,</span> <span class="n">writeln</span><span class="p">;</span>
  <span class="n">writeln</span><span class="p">(</span><span class="s">"testing odd()"</span><span class="p">);</span>
  <span class="n">write</span><span class="p">(</span><span class="s">"testing with even argument (expecting: false): "</span><span class="p">);</span>
  <span class="k">assert</span><span class="p">(</span><span class="kc">false</span> <span class="p">==</span> <span class="n">odd</span><span class="p">(</span><span class="mi">4</span><span class="p">));</span>
  <span class="n">write</span><span class="p">(</span><span class="s">"pass\ntesting with odd value (expecting: true): "</span><span class="p">);</span>
  <span class="k">assert</span><span class="p">(</span><span class="kc">true</span> <span class="p">==</span> <span class="n">odd</span><span class="p">(</span><span class="mi">3</span><span class="p">));</span>
  <span class="n">writeln</span><span class="p">(</span><span class="s">"pass\n odd() passed all tests (2)!"</span><span class="p">);</span>
<span class="p">}</span></code></pre></figure>

<h3 id="die-funktion">Die Funktion</h3>
<p>Die von mir bevorzugte Variante ist b). Da geprüft werden soll ob ein spezifisches Bit gesetzt ist, wählen wir die <code class="language-plaintext highlighter-rouge">und</code>-Verknüpfung, da diese folgende Eigenschaften hat:</p>
<table style="align-content:space-around; padding:0.5em">
<tr>
<th style="text-align:center; align-content:space-around; padding:0.25em">&amp;</th><th style="text-align:center; align-content:space-around; padding:0.25em">0</th><th style="text-align:center; align-content:space-around; padding:0.25em">1</th>
</tr>
<tr>
<th style="text-align:center; align-content:space-around; padding:0.25em">0</th><td style="text-align:center; align-content:space-around; padding:0.25em">0</td><td style="text-align:center; align-content:space-around; padding:0.25em">0</td>
</tr>
<tr>
<th style="text-align:center; align-content:space-around; padding:0.25em">1</th><td style="text-align:center; align-content:space-around; padding:0.25em">0</td><td style="text-align:center; align-content:space-around; padding:0.25em">1</td>
</tr>      
</table>
<p>Da wir keine Zwischenschritte haben können wir die Rechnung direkt in der <code class="language-plaintext highlighter-rouge">return</code>-Anweisung vornehemen, womit der Quelcode dann folgende Form annimmt:</p>

<figure class="highlight"><pre><code class="language-d" data-lang="d"><span class="nd">@safe</span> <span class="nd">@nogc</span> <span class="k">nothrow</span> <span class="k">pure</span>
<span class="kt">bool</span> <span class="n">odd</span><span class="p">(</span><span class="k">immutable</span> <span class="kt">ulong</span> <span class="n">n</span><span class="p">)</span>
<span class="p">{</span>
  <span class="k">return</span> <span class="p">(</span><span class="mi">1</span> <span class="p">==</span> <span class="p">(</span><span class="n">n</span> <span class="p">&amp;</span> <span class="mi">1</span><span class="p">));</span>
<span class="p">}</span>
<span class="c1">// hier folgen die Unittests</span></code></pre></figure>

<p>DMD compiliert oben stehendes zu nach stehenden Assembler Zeilen:</p>

<figure class="highlight"><pre><code class="language-asm" data-lang="asm">and       RDI,1
mov       EAX,1
cmp       RDI,RAX
setz      AL
ret</code></pre></figure>

<h4 id="variante-a">Variante a)</h4>
<p>Der Vollständigkeit halber hier noch D-Code und Assembler für Variante a):</p>

<figure class="highlight"><pre><code class="language-d" data-lang="d"><span class="nd">@safe</span> <span class="nd">@nogc</span> <span class="k">nothrow</span> <span class="k">pure</span>
<span class="kt">bool</span> <span class="n">mododd</span><span class="p">(</span><span class="k">immutable</span> <span class="kt">ulong</span> <span class="n">n</span><span class="p">)</span>
<span class="p">{</span>
  <span class="k">return</span> <span class="p">(</span><span class="mi">1</span> <span class="p">==</span> <span class="p">(</span><span class="n">n</span> <span class="p">%</span> <span class="mi">2</span><span class="p">));</span>
<span class="p">}</span></code></pre></figure>

<p>Wie schaut nun der Assembler-Code aus? Erwartet hatte ich etwas in folgender Form:</p>

<figure class="highlight"><pre><code class="language-asm" data-lang="asm">mov       RAX,RDI
mov       ECX,2
xor       EDX,EDX
div       RCX
cmp       RDX,1
setz      AL
ret</code></pre></figure>

<p>Wobei mir nicht klar ist, warum er das EDX-Register löscht in dem er es mir mit sich selbst »exklusiv odert«?</p>

<p>Da moderne Compiler »mitdenken« und optimieren sehen wir einen alten bekannten wieder:</p>

<figure class="highlight"><pre><code class="language-asm" data-lang="asm">and       RDI,1
mov       EAX,1
cmp       RDI,RAX
setz      AL
ret</code></pre></figure>

<p>Der Compiler substituiert das Modulo durch den MSB-Set-Test.</p>

<h2 id="fazit">Fazit</h2>
<p>Es ist ineteressant, Dinge mal anders zu machen, um Verständnis für Abläufe zu entwickeln über welche man sich kaum mehr Gedanken macht. Augenscheinlich ist dies wegen der höheren Kerntakte und schieren Speichermengen heute auch kaum mehr notwendig, aber je nach Platform ist händische Voroptimierung durchaus sinnvoll, weil moderne Compiler dann nicht die Nachlässigkeiten von Programmieren oder Codegeneratoren ausbügeln müssen, sondern kleinteiliger optimieren können.</p>

<h2 id="changelog">Changelog</h2>
<p>2026-03-09: Referenzen hinzugefügt.
2026-03-15: Umstelung Tabelle auf HTML, da jekyll keine MArkdown-Table-Syntax unterstützt.</p>
<h2 id="referenzen">Referenzen</h2>

<div class="footnotes" role="doc-endnotes">
  <ol>
    <li id="fn:1">
      <p><a href="https://dlang.org/spec/unittest.html">https://dlang.org/spec/unittest.html</a> “(2026-03-09)” <a href="#fnref:1" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
  </ol>
</div>]]></content><author><name></name></author><category term="programmierung" /><category term="programmierung" /><category term="d" /><category term="d-lang" /><category term="integer" /><category term="ganzzahlen" /><category term="msb" /><summary type="html"><![CDATA[Einleitung Wenn man von einer anderen Programmiersorache kommt – in meinem Fall Pascal — und sich an neue heran wagt, sucht man seine vertrauten Helfelein.]]></summary></entry></feed>