<?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[binary add]]></title><description><![CDATA[<p>hi,</p>
<p>ich moechte zwei binaer strings addieren...</p>
<p>ich weiss das folgender code nicht besonders schoen ist, wie kann ich die lesbarkeit/performance verbessern?</p>
<pre><code>#include &lt;iostream&gt;
#include &lt;string&gt;
#include &lt;vector&gt;
using namespace std;

/*
a = &quot;1100&quot;
b = &quot;111&quot;
addiere beide strings und gebe folgendes zurueck: &quot;10011&quot;.
*/

string zeroPadding(string s, int bits) {
	for (int i = 0; i &lt; bits; i++) {
		s = &quot;0&quot; + s;
	}
	return s;
}

class MyPair {
public:
	char first;
	char second;
	MyPair(char first_, char second_): first(first_), second(second_) {}
};

string addBinary(string a, string b) {
	int len1 = a.size();
	int len2 = b.size();
	string result;
	char carry = '0';
	char sum = '0';                   // a=0,b=0       // a=0,b=1
	vector&lt;vector&lt;MyPair&gt;&gt; andVec = {{MyPair('0','0'), MyPair('1','0')},
	                                  // a=1,b=0       // a=1,b=1
								     {MyPair('1','0'), MyPair('0','1')}};
                                               // a=0,b=0       // a=0,b=1
	vector&lt;vector&lt;MyPair&gt;&gt; andVecWithCarry = {{MyPair('1','0'), MyPair('1=0','1')},
	                                           // a=1,b=0       // a=1,b=1
								              {MyPair('0','1'), MyPair('1','1')}};	
	if (len1 &lt; len2) {
		a = zeroPadding(a, len2 - len1);
	} else if (len1 &gt; len2) {
		b = zeroPadding(b, len1 - len2);
	}

	for (int i = len1 - 1; i &gt;= 0; i--) {
		if (carry == '0') {
			auto p = andVec[a[i] - '0'][b[i] - '0'];
			sum = p.first;
			carry = p.second;
		} else if (carry == '1') {
			auto p = andVecWithCarry[a[i] - '0'][b[i] - '0'];
			sum = p.first;
			carry = p.second;
		}

		result = sum + result;
	}

	if (carry == '1') {
		result = carry + result;
	}

	return result;
}

int main() {
	// your code goes here

	cout &lt;&lt; addBinary(&quot;1100&quot;, &quot;111&quot;) &lt;&lt; endl;

	return 0;
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/topic/328106/binary-add</link><generator>RSS for Node</generator><lastBuildDate>Wed, 08 Jul 2026 15:04:48 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/328106.rss" rel="self" type="application/rss+xml"/><pubDate>Mon, 22 Sep 2014 21:25:30 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to binary add on Mon, 22 Sep 2014 21:25:30 GMT]]></title><description><![CDATA[<p>hi,</p>
<p>ich moechte zwei binaer strings addieren...</p>
<p>ich weiss das folgender code nicht besonders schoen ist, wie kann ich die lesbarkeit/performance verbessern?</p>
<pre><code>#include &lt;iostream&gt;
#include &lt;string&gt;
#include &lt;vector&gt;
using namespace std;

/*
a = &quot;1100&quot;
b = &quot;111&quot;
addiere beide strings und gebe folgendes zurueck: &quot;10011&quot;.
*/

string zeroPadding(string s, int bits) {
	for (int i = 0; i &lt; bits; i++) {
		s = &quot;0&quot; + s;
	}
	return s;
}

class MyPair {
public:
	char first;
	char second;
	MyPair(char first_, char second_): first(first_), second(second_) {}
};

string addBinary(string a, string b) {
	int len1 = a.size();
	int len2 = b.size();
	string result;
	char carry = '0';
	char sum = '0';                   // a=0,b=0       // a=0,b=1
	vector&lt;vector&lt;MyPair&gt;&gt; andVec = {{MyPair('0','0'), MyPair('1','0')},
	                                  // a=1,b=0       // a=1,b=1
								     {MyPair('1','0'), MyPair('0','1')}};
                                               // a=0,b=0       // a=0,b=1
	vector&lt;vector&lt;MyPair&gt;&gt; andVecWithCarry = {{MyPair('1','0'), MyPair('1=0','1')},
	                                           // a=1,b=0       // a=1,b=1
								              {MyPair('0','1'), MyPair('1','1')}};	
	if (len1 &lt; len2) {
		a = zeroPadding(a, len2 - len1);
	} else if (len1 &gt; len2) {
		b = zeroPadding(b, len1 - len2);
	}

	for (int i = len1 - 1; i &gt;= 0; i--) {
		if (carry == '0') {
			auto p = andVec[a[i] - '0'][b[i] - '0'];
			sum = p.first;
			carry = p.second;
		} else if (carry == '1') {
			auto p = andVecWithCarry[a[i] - '0'][b[i] - '0'];
			sum = p.first;
			carry = p.second;
		}

		result = sum + result;
	}

	if (carry == '1') {
		result = carry + result;
	}

	return result;
}

int main() {
	// your code goes here

	cout &lt;&lt; addBinary(&quot;1100&quot;, &quot;111&quot;) &lt;&lt; endl;

	return 0;
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2418753</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2418753</guid><dc:creator><![CDATA[c++11coder]]></dc:creator><pubDate>Mon, 22 Sep 2014 21:25:30 GMT</pubDate></item><item><title><![CDATA[Reply to binary add on Mon, 22 Sep 2014 21:45:44 GMT]]></title><description><![CDATA[<pre><code>string zeroPadding(string s, int bits) {
	for (int i = 0; i &lt; bits; i++) {
		s = &quot;0&quot; + s;
	} 

	return s;
}

class SumCarry {
public:
	char sum;
	char carry;
	SumCarry(char sum_, char carry_): sum(sum_), carry(carry_) {}
};

string addBinary(string a, string b) {
	int len1 = a.size();
	int len2 = b.size();
	string result('0', max(len1,len2)+1); // allocate one more carry bit
	char carry = '0';
	char sum = '0';                   // a=0,b=0       // a=0,b=1
	vector&lt;vector&lt;SumCarry&gt;&gt; andVec = {{SumCarry('0','0'), SumCarry('1','0')},
	                                  // a=1,b=0       // a=1,b=1
								     {SumCarry('1','0'), SumCarry('0','1')}};
                                               // a=0,b=0       // a=0,b=1
	vector&lt;vector&lt;SumCarry&gt;&gt; andVecWithCarry = {{SumCarry('1','0'), SumCarry('1=0','1')},
	                                           // a=1,b=0       // a=1,b=1
								              {SumCarry('0','1'), SumCarry('1','1')}};	
	if (len1 &lt; len2) {
		a = zeroPadding(a, len2 - len1);
	} else if (len1 &gt; len2) {
		b = zeroPadding(b, len1 - len2);
	}

	int i = 0;
	for (i = a.size() - 1; i &gt;= 0; i--) {
		int indexX = a[i] - '0';
		int indexY = b[i] - '0';

		if (carry == '0') {
			auto p = andVec[indexX][indexY];
			sum = p.sum;
			carry = p.carry;
		} else if (carry == '1') {
			auto p = andVecWithCarry[indexX][indexY];
			sum = p.sum;
			carry = p.carry;
		}

		result[i+1] = sum;
	}

	if (carry == '1') {
		result[0] = carry;
	} else {
		result.erase(result.begin(), result.begin()+1);
	}

	return result;
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2418755</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2418755</guid><dc:creator><![CDATA[c++11coder]]></dc:creator><pubDate>Mon, 22 Sep 2014 21:45:44 GMT</pubDate></item><item><title><![CDATA[Reply to binary add on Mon, 22 Sep 2014 21:51:43 GMT]]></title><description><![CDATA[<p>c++11coder schrieb:</p>
<blockquote>
<p>ich weiss das folgender code nicht besonders schoen ist, wie kann ich die lesbarkeit/performance verbessern?</p>
</blockquote>
<p>Kommt drauf an, was das Ziel ist. Rechnen mit binären Strings und Performance passt von Grund auf nicht zusammen. Wenn es also um eine echte Anwendung geht, dann wäre die richtige Hilfestellung, dir zu helfen, wie du diesen Fall von Vorhinein vermeiden kannst. Wenn es um die Addition binärer Strings als Selbstzweck geht, dann geht das natürlich trotzdem viel schöner und schneller. Ich gucke jetzt absichtlich nicht bei Wikipedia, um dir einen Einblick zu geben, wie man solche Probleme angeht. Denn der erste Tipp ist: Mal bei Wikipedia gucken, ob es effiziente Additionsalgorithmen für das Binärsystem gibt.</p>
<p>Weitere technische Fehler, die sofort auffallen:</p>
<pre><code>'1=0'
</code></pre>
<p>Hast etwa du den Code abgetippt fürs Forum oder steht das wirklich da? Beides ist nicht gut. Immer Copy &amp; Paste fürs Forum benutzen. Oder Compilerwarnungen aktivieren und beachten. Je nachdem, welche Antwort zutrifft.</p>
<p>Statische Lookuptables initialisiert man nicht bei jedem Funktionsaufruf. Statische Felder stopft man nicht in einen Vector. Erst recht nicht &quot;rechteckige&quot; Felder in einen vector&lt;vector&gt;.<br />
Ein Lookuptable für 4 Kombinationen klingt sowieso reichlich ineffizient, würde ich gar nicht erst so machen.</p>
<p>Das mit dem Padding sieht spontan auch nicht elegant aus. Geht sicher genau so gut oder besser, wenn man es einfach weg lässt.</p>
<p>Und jetzt gucke ich mal auf Wikipedia nach und vielleicht schreibe ich selber was, mal sehen, habe gerade anderweitig zu tun.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2418756</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2418756</guid><dc:creator><![CDATA[SeppJ]]></dc:creator><pubDate>Mon, 22 Sep 2014 21:51:43 GMT</pubDate></item><item><title><![CDATA[Reply to binary add on Tue, 23 Sep 2014 01:04:26 GMT]]></title><description><![CDATA[<p>Habe etwas Zeit gefunden. Erst einmal die einfachste Implementierung, die mir eingefallen ist. Nutzt die gleiche Methode, wie dein Programm, sollte aber effizienter und lesbarer sein als der Lookuptable. Das Padding war übrigens vielleicht doch eine gute Idee, zumindest, wenn man es einfach haben will <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>
<pre><code>string binary_add(string lhs, string rhs)
{
  size_t size = max(lhs.size(), rhs.size()); 
  lhs.insert(lhs.begin(), size - lhs.size(), '0');
  rhs.insert(rhs.begin(), size - rhs.size(), '0'); 
  unsigned int carry = 0;
  string result(size, '\0');

  for (size_t i = size; i != size_t(-1); --i)
    {
      unsigned int intermediate_result = carry + lhs[i] - '0' + rhs[i] - '0';
      switch (intermediate_result)
        {
        case 0:
          carry = 0;
          result[i] = '0';
          break;
        case 1:
          carry = 0;
          result[i] = '1';
          break;
        case 2:
          carry = 1;
          result[i] = '0';
          break;
        case 3:
          carry = 1;
          result[i] = '1';
          break;
        }
    }

  if (carry) result.insert(result.begin(), '1');

  return result;
}
</code></pre>
<p>Das ganze ist halt relativ unschön, da die Zahlen hier big endian dargestellt werden. Daher muss man rückwärts durch die Strings laufen (damit kann man ja noch leben) und mehrmals Einfügungen am Anfang machen (wofür strings eine denkbar ungeeignete Datenstruktur sind) und hat zudem noch zwei teure Stringkopien<sup>*</sup>.</p>
<p>Und das war's dann auch schon. Denn ich fand keinen coolen Trick für binäre Addition. Auf Wikipedia wird eine &quot;long carry&quot; Methode beschrieben. Das scheint aber eine Methode rein für den menschlichen Gebrauch mit Zettel und Stift zu sein. Denn es geht um das Ausnutzen gewisser Muster in den Zahlen. Ein Mensch findet diese auf einen Blick, aber der Computer muss letztlich doch alle Ziffern angucken, genau wie jetzt auch. Ob er dann mit diesen Ziffern eine triviale Rechenoperation durchführt oder darin Muster sucht, ist keine Vereinfachung, ja eher eine Verkomplizierung. Die Methode ist interessant und werde ich mir merken, für den Fall, dass ich mal in die Verlegenheit komme, binär auf Papier zu addieren, aber ich werde es nicht im Computer implementieren.</p>
<p><sup>*</sup>: Das sind natürlich lösbare Probleme, aber dann ist der Code nicht mehr schön und knackig und man hat bei jedem Zugriff einen Haufen if-Abfragen, die man sich hier spart.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2418763</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2418763</guid><dc:creator><![CDATA[SeppJ]]></dc:creator><pubDate>Tue, 23 Sep 2014 01:04:26 GMT</pubDate></item><item><title><![CDATA[Reply to binary add on Wed, 24 Sep 2014 12:16:16 GMT]]></title><description><![CDATA[<p>SeppJ schrieb:</p>
<blockquote>
<pre><code>unsigned int intermediate_result = carry + lhs[i] - '0' + rhs[i] - '0';
      switch (intermediate_result)
        {
        case 0:
          carry = 0;
          result[i] = '0';
          break;
        case 1:
          carry = 0;
          result[i] = '1';
          break;
        case 2:
          carry = 1;
          result[i] = '0';
          break;
        case 3:
          carry = 1;
          result[i] = '1';
          break;
        }
</code></pre>
</blockquote>
<p>Warum nicht:</p>
<pre><code>unsigned int intermediate_result = (carry + lhs[i] - '0' + rhs[i] - '0');
result[i] = intermediate_result &amp; 0x01;
carry = intermediate_result &amp; 0x02;
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2418968</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2418968</guid><dc:creator><![CDATA[traeger_0]]></dc:creator><pubDate>Wed, 24 Sep 2014 12:16:16 GMT</pubDate></item><item><title><![CDATA[Reply to binary add on Wed, 24 Sep 2014 12:17:28 GMT]]></title><description><![CDATA[<p>ich meinte natuerlich:</p>
<pre><code>result[i] = intermediate_result &amp; 0x01 + '0';
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2418969</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2418969</guid><dc:creator><![CDATA[trager_0]]></dc:creator><pubDate>Wed, 24 Sep 2014 12:17:28 GMT</pubDate></item><item><title><![CDATA[Reply to binary add on Wed, 24 Sep 2014 17:08:11 GMT]]></title><description><![CDATA[<p>traeger_0 schrieb:</p>
<blockquote>
<p>Warum nicht: [...]</p>
</blockquote>
<p>Weil:</p>
<p>SeppJ schrieb:</p>
<blockquote>
<p>Habe etwas Zeit gefunden. Erst einmal die <strong>einfachste</strong> Implementierung, die mir eingefallen ist. Nutzt die gleiche Methode, wie dein Programm, sollte aber effizienter und <strong>lesbarer</strong> sein als der Lookuptable. Das Padding war übrigens vielleicht doch eine gute Idee, zumindest, wenn man es <strong>einfach</strong> haben will <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>PS: Warum schreibst du 0x01 statt 1 und 0x02 statt 2? Ist dezimal nicht 0x539 genug?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2419022</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2419022</guid><dc:creator><![CDATA[SeppJ]]></dc:creator><pubDate>Wed, 24 Sep 2014 17:08:11 GMT</pubDate></item><item><title><![CDATA[Reply to binary add on Thu, 25 Sep 2014 08:13:22 GMT]]></title><description><![CDATA[<p>SeppJ schrieb:</p>
<blockquote>
<p>PS: Warum schreibst du 0x01 statt 1 und 0x02 statt 2? Ist dezimal nicht 0x539 genug?</p>
</blockquote>
<p>Reine Angewohnheit aus meiner fruehen hardwarenahen Sozialisierungsphase. Die Regel in der Firma war, dass alle Bitmasken hexadezimal geschrieben werden mussten.</p>
<p>Sobald es der Compiler unterstuetzt wird auf binary literals umgestellt.</p>
<p>Da war im Uebrigen noch ein Fehler drin, das Carry-bit muss auf 0/1 geschoben werden.</p>
<pre><code>unsigned int intermediate_result = carry + (lhs[i] - '0') + (rhs[i] - '0');

result[i] = intermediate_result &amp; 0b01 + '0'; // mask binary sum
carry = (intermediate_result &amp; 0b10)&gt;&gt;1; // mask carry and shift to LSB
</code></pre>
<p>Ich empfinde das einfacher zu lesen und zu verstehen als einen Case-switch, aber das ist wohl eher dem Umfeld in dem ich programmieren gelernt habe geschuldet.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2419097</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2419097</guid><dc:creator><![CDATA[traeger_0]]></dc:creator><pubDate>Thu, 25 Sep 2014 08:13:22 GMT</pubDate></item></channel></rss>