<rss version="2.0">
  <channel>
    <title>Longform on Nathan Heller</title>
    <link>https://blog.naheller.com/categories/longform/</link>
    <description></description>
    
    <language>en</language>
    
    <lastBuildDate>Sun, 24 May 2026 12:54:44 +0700</lastBuildDate>
    
    <item>
      <title>Two&#39;s Complement</title>
      <link>https://blog.naheller.com/2026/05/24/twos-complement/</link>
      <pubDate>Sun, 24 May 2026 12:54:44 +0700</pubDate>
      
      <guid>http://nxte.micro.blog/2026/05/24/twos-complement/</guid>
      <description>&lt;p&gt;Two&amp;rsquo;s Complement is a way to represent positive and negative numbers in binary. It&amp;rsquo;s useful because we want a way to represent each number&amp;rsquo;s inverse within a limited number of bits.&lt;/p&gt;
&lt;h2 id=&#34;the-sign-bit&#34;&gt;The sign bit&lt;/h2&gt;
&lt;p&gt;Putting aside two&amp;rsquo;s complement, the &amp;ldquo;naive&amp;rdquo; way to represent a negative number is to simply use its highest order bit as a &amp;ldquo;sign&amp;rdquo; bit. That is, &lt;code&gt;0&lt;/code&gt; for positive and &lt;code&gt;1&lt;/code&gt; for negative.&lt;/p&gt;
&lt;p&gt;With 4 bits&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;5 = 0101
-5 = 1101
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;With 8 bits:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt; 5 = 00000101
-5 = 10000101
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;However with this method, arithmetic operations come out wrong. for example:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;5 + (-5) = 2

 0101
+1101
-----
10010 = 2
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We also have the curious existence of &lt;code&gt;-0&lt;/code&gt;, if we flip the sign bit on &lt;code&gt;0&lt;/code&gt;:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt; 0 = 0000
-0 = 1000
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;So we need a better method.&lt;/p&gt;
&lt;h2 id=&#34;ones-complement&#34;&gt;One&amp;rsquo;s Complement&lt;/h2&gt;
&lt;p&gt;This method inverts all the bits in a number to get its positive/negative equivalent, or &amp;ldquo;complement&amp;rdquo;. The reason it&amp;rsquo;s called &lt;em&gt;One&amp;rsquo;s&lt;/em&gt; Complement is that adding a number to its inverse results in a sequence of all ones: &lt;code&gt;1111&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Notice that left-most bit still acts as a sign bit:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt; 5 = 0101
-5 = 1010

 7 = 0111
-7 = 1000
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Unfortunately we still have &lt;code&gt;-0&lt;/code&gt;, but arithmetic operations are &lt;em&gt;more&lt;/em&gt; correct than before:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt; 0 = 0000
-0 = 1111

5 + (-5) = -0

 0101
+1010
-----
 1111 = -0
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In fact, arithmetic results seem to be off by one:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;5 + (-3) = 1

   0101
+  1100
-------
(1)0001 = 1 (should be 2)

6 + (-2) = 3

   0110
+  1101
-------
(1)0011 = 3 (should be 4)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;By adding 1 to any of the above results, we can get the correct result.&lt;/p&gt;
&lt;h2 id=&#34;twos-complement&#34;&gt;Two&amp;rsquo;s Complement&lt;/h2&gt;
&lt;p&gt;With Two&amp;rsquo;s Complement we get rid of &lt;code&gt;-0&lt;/code&gt;, which shifts the negative numbers over by one. For example, &lt;code&gt;-1&lt;/code&gt; in One&amp;rsquo;s Complement is &lt;code&gt;1110&lt;/code&gt;, whereas in Two&amp;rsquo;s Complement it is &lt;code&gt;1111&lt;/code&gt;. This has the effect of &amp;ldquo;incrementing&amp;rdquo; it in binary, thereby giving us the added 1 we wanted in order to achieve correct arithmetic results.&lt;/p&gt;
&lt;p&gt;This method is called &lt;em&gt;Two&amp;rsquo;s&lt;/em&gt; Complement because when adding a number to its inverse, each addition operation results in the binary value for 2. This effectively &amp;ldquo;carries the one&amp;rdquo; all the way over to the left and into the overflow, giving us a sequence of zeroes. And any number added to its inverse should indeed be zero.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;5 + (-5) = 0

   0101
+  1011
-------
(1)0000 = 0
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Another interesting property of Two&amp;rsquo;s Complement is the place values. From right to left in a 4-bit sequence, we have 1&amp;rsquo;s, 2&amp;rsquo;s, and 4&amp;rsquo;s places as expected. However the final bit is actually the -8&amp;rsquo;s place.&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;1000    -8 (-8 + 0 + 0 + 0) = -8
1001    -7 (-8 + 0 + 0 + 1) = -7
1010    -6 (-8 + 0 + 2 + 0) = -6
.
.
.
1111    -1 (-8 + 4 + 2 + 1) = -1
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;So in addition to acting as the sign bit, that left-most bit also has mathematical meaning, which is what allows the arithmetic to work out.&lt;/p&gt;
&lt;h3 id=&#34;inverting-a-number-in-twos-complement&#34;&gt;Inverting a number in Two&amp;rsquo;s Complement&lt;/h3&gt;
&lt;p&gt;To invert a number in Two&amp;rsquo;s Complement, we need to flip its bits and add one. This is one more step than with One&amp;rsquo;s Complement, where we only need to flip the bits.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;0101 = 5
1010 (flip bits)
1011 = -5 (add one)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This is fairly trivial, but something that hardware designers need to keep in mind when building circuits that perform arithmetic.&lt;/p&gt;
</description>
    </item>
    
  </channel>
</rss>