{"id":595,"date":"2018-05-23T03:09:42","date_gmt":"2018-05-23T03:09:42","guid":{"rendered":"http:\/\/www.onux.com\/jspp\/blog\/?p=595"},"modified":"2021-10-12T19:37:25","modified_gmt":"2021-10-12T19:37:25","slug":"bitwise-operators-and-specification-compliant-integer-overflow-optimizations","status":"publish","type":"post","link":"https:\/\/www.onux.com\/jspp\/blog\/bitwise-operators-and-specification-compliant-integer-overflow-optimizations\/","title":{"rendered":"Bitwise Operators and Specification-compliant Integer Overflow Optimizations"},"content":{"rendered":"<p>If you use the upcoming <a href=\"https:\/\/docs.onux.com\/en-US\/Developers\/JavaScript-PP\/Standard-Library\/System\/UInteger32\/isEven\" rel=\"noopener noreferrer\" target=\"_blank\">UInteger32.isEven<\/a> or <a href=\"https:\/\/docs.onux.com\/en-US\/Developers\/JavaScript-PP\/Standard-Library\/System\/UInteger32\/isOdd\" rel=\"noopener noreferrer\" target=\"_blank\">isOdd<\/a> methods, you&#8217;ll notice that it uses a <a href=\"https:\/\/docs.onux.com\/en-US\/Developers\/JavaScript-PP\/Language\/Reference\/Expressions\/bitwise-operators\/and\" rel=\"noopener noreferrer\" target=\"_blank\">bitwise AND operation<\/a>. The reason, as described in a previous post, is because <a href=\"https:\/\/www.onux.com\/jspp\/blog\/standard-library-performance-iseven-and-isodd\/\" rel=\"noopener noreferrer\" target=\"_blank\">it improves performance<\/a>.<\/p>\n<p>However, while this is straightforward for all other integer wrapper classes, <code>UInteger32<\/code> is an exception. According to ECMAScript 3 11.10:<\/p>\n<blockquote><p>\nThe production A : A @B, where @ is one of the bitwise operators in the productions above, is evaluated as follows:<\/p>\n<ol>\n<li>Evaluate A.<\/li>\n<li>Call GetValue(Result(1)).<\/li>\n<li>Evaluate B.<\/li>\n<li>Call GetValue(Result(3)).<\/li>\n<li><strong style=\"color:#ff0000\">Call ToInt32(Result(2)).<\/strong><\/li>\n<li><strong style=\"color:#ff0000\">Call ToInt32(Result(4)).<\/strong><\/li>\n<li>Apply the bitwise operator @ to Result(5) and Result(6). <strong style=\"color:#ff0000\">The result is a signed 32 bit integer.<\/strong><\/li>\n<li>Return Result(7).<\/li>\n<\/ol>\n<\/blockquote>\n<p>The operands (and, thus, the result type) for the bitwise AND operation in ECMAScript are converted to 32-bit signed integers. System.UInteger32 represents an unsigned 32-bit integer.<\/p>\n<p>This is inconvenient because we&#8217;d obviously have to fall back to the slower modulus operation for isEven\/isOdd on UInteger32. Unless&#8230;<\/p>\n<pre class=\"brush:jspp\">\r\n((Math.pow(2, 32) + 1) >>> 0 | 0) & 1 \/\/ true\r\n((Math.pow(2, 32) + 2) >>> 0 | 0) & 1 \/\/ false\r\n<\/pre>\n<p>We can take advantage of overflow behavior. (Note: Since we&#8217;re able to get the correct result by leveraging overflow behavior, we actually don&#8217;t perform the extraneous <a href=\"https:\/\/docs.onux.com\/en-US\/Developers\/JavaScript-PP\/Language\/Reference\/Expressions\/bitwise-operators\/unsigned-right-shift\" rel=\"noopener noreferrer\" target=\"_blank\">zero-fill right shift<\/a> as illustrated in the example.)<\/p>\n<p>This is completely safe because:<\/p>\n<p>A) Mathematically, in base 2, the last bit will always be 1 for odd numbers and 0 for even numbers&#8230; <em>no matter how big the number is.<\/em><\/p>\n<p>B) Bitwise AND will compare both bits in equal-length binary forms. Thus, no matter how big the number is, when you AND against 1, it will always be 0000001 (or zero-padded to whatever length is needed). Therefore, all the preceding bits don&#8217;t matter because they will always be ANDed against a zero bit. The only bit that matters is the trailing bit; see A for why this will always work.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>If you use the upcoming UInteger32.isEven or isOdd methods, you&#8217;ll notice that it uses a bitwise AND operation. The reason, as described in a previous post, is because it improves performance. However, while this is straightforward for all other integer wrapper classes, UInteger32 is an exception. According to ECMAScript 3 11.10: The production A : &hellip; <a href=\"https:\/\/www.onux.com\/jspp\/blog\/bitwise-operators-and-specification-compliant-integer-overflow-optimizations\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Bitwise Operators and Specification-compliant Integer Overflow Optimizations&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[3,2,15],"tags":[],"_links":{"self":[{"href":"https:\/\/www.onux.com\/jspp\/blog\/wp-json\/wp\/v2\/posts\/595"}],"collection":[{"href":"https:\/\/www.onux.com\/jspp\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.onux.com\/jspp\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.onux.com\/jspp\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.onux.com\/jspp\/blog\/wp-json\/wp\/v2\/comments?post=595"}],"version-history":[{"count":22,"href":"https:\/\/www.onux.com\/jspp\/blog\/wp-json\/wp\/v2\/posts\/595\/revisions"}],"predecessor-version":[{"id":1255,"href":"https:\/\/www.onux.com\/jspp\/blog\/wp-json\/wp\/v2\/posts\/595\/revisions\/1255"}],"wp:attachment":[{"href":"https:\/\/www.onux.com\/jspp\/blog\/wp-json\/wp\/v2\/media?parent=595"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.onux.com\/jspp\/blog\/wp-json\/wp\/v2\/categories?post=595"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.onux.com\/jspp\/blog\/wp-json\/wp\/v2\/tags?post=595"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}