{"id":45034,"date":"2015-05-26T07:00:00","date_gmt":"2015-05-26T21:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2015\/05\/26\/the-tadpole-operators-explained\/"},"modified":"2025-12-23T07:10:44","modified_gmt":"2025-12-23T15:10:44","slug":"20150526-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20150526-00\/?p=45034","title":{"rendered":"The tadpole operators explained"},"content":{"rendered":"<p>Last time,\u00b9 I introduced <a title=\"New C++ experimental feature: The tadpole operators\" href=\"https:\/\/devblogs.microsoft.com\/oldnewthing\/20150525-00\/?p=45044\"> the tadpole operators<\/a>. As you have probably figured out by now, it was a joke. There are no new tadpole operators.<\/p>\n<p>But the sample code works. What&#8217;s going on?<\/p>\n<p>The tadpole operators are pseudo-operators, like <a href=\"https:\/\/web.archive.org\/web\/20100607075036\/http:\/\/blogs.msdn.com\/b\/ericlippert\/archive\/2010\/04\/01\/somelastminutefeatures.aspx\"> the goes to operator<\/a> or <a href=\"https:\/\/news.ycombinator.com\/item?id=9602611\"> the sproing operator<\/a>: They take advantage of existing language features, and come with a creative story.<\/p>\n<p>The tadpole operators exploit two&#8217;s complement arithmetic and overflow.\u00b2 The <code>__ENABLE_<wbr \/>EXPERIMENTAL_<wbr \/>TADPOLE_<wbr \/>OPERATORS<\/code> is just a red herring.<\/p>\n<p>Start with the identity for two&#8217;s complement negation<\/p>\n<pre>-x = ~x + 1\r\n<\/pre>\n<p>then move the <code>-x<\/code> to the right hand side and the <code>~x<\/code> to the left hand side:<\/p>\n<pre>-~x = x + 1\r\n<\/pre>\n<p>If that was too fast for you, we can do it a different way: start with the identity for two&#8217;s complement negation<\/p>\n<pre>-x = ~x + 1\r\n<\/pre>\n<p>subtract 1 from both sides<\/p>\n<pre>-x - 1 = ~x\r\n<\/pre>\n<p>and finally, negate both sides<\/p>\n<pre>x + 1 = -~x\r\n<\/pre>\n<p>To get the decrement tadpole operator, start with<\/p>\n<pre>-x = ~x + 1\r\n<\/pre>\n<p>and substitute <code>x = -y<\/code>:<\/p>\n<pre>-(-y) = ~-y + 1\r\n<\/pre>\n<p>subtract <code>1<\/code> from both sides and simplify <code>-(-y)<\/code> to <code>y<\/code>.<\/p>\n<pre>y - 1 = ~-y\r\n<\/pre>\n<p><b>Update<\/b>: <a href=\"http:\/\/blogs.msdn.com\/b\/oldnewthing\/archive\/2015\/05\/25\/10616865.aspx#10617200\"> Justin Olbrantz (Quantam)<\/a> and <a href=\"http:\/\/blogs.msdn.com\/b\/oldnewthing\/archive\/2015\/05\/26\/10617079.aspx#10617246\"> Ben Voigt<\/a> provide a simpler derivation, starting with the identity for two&#8217;s complement negation.<\/p>\n<table border=\"0\" cellpadding=\"3\">\n<tbody>\n<tr>\n<td><code>-x = ~x + 1<\/code><\/td>\n<td>&nbsp;<\/td>\n<td>&nbsp;<\/td>\n<\/tr>\n<tr>\n<td>&nbsp;<\/td>\n<td align=\"center\">Rearrange terms<\/td>\n<td><code>~x = -x - 1<\/code><\/td>\n<\/tr>\n<tr>\n<td>Let <code>x = ~y<\/code><\/td>\n<td>&nbsp;<\/td>\n<td>Let <code>x = -y<\/code><\/td>\n<\/tr>\n<tr>\n<td><code>-~y = ~(~y) + 1<\/code><\/td>\n<td>&nbsp;<\/td>\n<td><code>~-y = -(-y) - 1<\/code><\/td>\n<\/tr>\n<tr>\n<td><code>-~y = y + 1<\/code><\/td>\n<td>&nbsp;<\/td>\n<td><code>~-y = y - 1<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>\u00b9Why didn&#8217;t I post it on April 1st? Well, for one thing, April 1st is overcrowded. Second, it would have interfered with the run-up to the \/\/build conference. And third, yesterday was a holiday in the United States, and I tend to schedule lighter fare on holidays.<\/p>\n<p>\u00b2This means that they don&#8217;t work on a machine that does not use two&#8217;s complement, or one which checks overflow. Still, maybe they&#8217;ll be useful if you&#8217;re entering the <a href=\"http:\/\/ioccc.org\/\"> IOCCC<\/a> or some other contest which values minimal code size or obfuscation (or both).<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Combining two things in an unintuitive way.<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[25],"class_list":["post-45034","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>Combining two things in an unintuitive way.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/45034","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=45034"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/45034\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=45034"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=45034"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=45034"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}