{"id":1214,"date":"2016-10-20T13:39:33","date_gmt":"2016-10-20T13:39:33","guid":{"rendered":"https:\/\/block.arch.ethz.ch\/blog\/?p=1214"},"modified":"2016-10-20T13:42:11","modified_gmt":"2016-10-20T13:42:11","slug":"bitwise-operators-in-python","status":"publish","type":"post","link":"https:\/\/block.arch.ethz.ch\/blog\/2016\/10\/bitwise-operators-in-python\/","title":{"rendered":"Bitwise operators in Python"},"content":{"rendered":"<p>Python has logical operators (like &#8216;and&#8217;) and bitwise operators (like &#8216;&#038;&#8217;). Bitwise operators are not that common in Python code, but they can be extremely useful in some cases. For example, in <a href=\"http:\/\/developer.rhino3d.com\/guides\/#rhinopython\" target=\"_blank\">RhinoPython<\/a> they are used to work with geometry type filters.<\/p>\n<p><!--more--><\/p>\n<p>The geometry types in the <a href=\"https:\/\/github.com\/mcneel\/rhinoscriptsyntax\/tree\/master\/Scripts\/rhinoscript\" target=\"_blank\">rhinoscripsyntax package<\/a> are defined in the <a href=\"https:\/\/github.com\/mcneel\/rhinoscriptsyntax\/blob\/master\/Scripts\/rhinoscript\/selection.py\" target=\"_blank\">selection module<\/a> and can be accessed like this:<\/p>\n<pre class=\"brush:py\"> \r\nimport rhinoscriptsyntax as rs\r\n\r\nprint rs.filter.point    # prints 1\r\nprint rs.filter.curve    # prints 4\r\nprint rs.filter.surface  # prints 8\r\n<\/pre>\n<p>The entire list of values can be found on <a href=\"https:\/\/github.com\/mcneel\/rhinoscriptsyntax\/blob\/master\/Scripts\/rhinoscript\/selection.py\" target=\"_blank\">GitHub<\/a>, but i will copy the code here for simplicity:<\/p>\n<pre class=\"brush:py\">\r\nclass filter:\r\n    allobjects = 0\r\n    point = 1\r\n    pointcloud = 2\r\n    curve = 4\r\n    surface = 8\r\n    polysurface = 16\r\n    mesh = 32\r\n    light = 256\r\n    annotation = 512\r\n    instance = 4096\r\n    textdot = 8192\r\n    grip = 16384\r\n    detail = 32768\r\n    hatch = 65536\r\n    morph = 13072\r\n    cage = 134217728\r\n    phantom = 268435456\r\n    clippingplane = 536870912\r\n    extrusion = 1073741824\r\n<\/pre>\n<p>Notice that the values correspond to powers of 2. Therefore they each correspond to a different digit in the binary system:<\/p>\n<pre class=\"brush:py\">\r\nprint bin(rs.filter.point)    # prints '0b1'\r\nprint bin(rs.filter.curve)    # prints '0b100'\r\nprint bin(rs.filter.surface)  # prints '0b1000' \r\n<\/pre>\n<p>This is where bitwise operators come in. Bitwise operators compare corresponding digits in two binary numbers and return a result in binary form accordingly. <\/p>\n<p>Bitwise &#8216;and&#8217; (&#038;) returns a binary number with 1 at digits where both of the corresponding digits of the operands are 1:<\/p>\n<pre class=\"brush:py\">\r\nprint 0 & 1    # prints 0 (0000), since 0000 'and' 0001 => 0000\r\nprint 2 & 3    # prints 2 (0010), since 0010 'and' 0011 => 0010\r\nprint 2 & 7    # prints 2 (0010), since 0010 'and' 0111 => 0010 \r\nprint 15 & 10  # prints 10 (1010), since 1111 'and' 1010 => 1010  \r\n<\/pre>\n<p>Bitwise &#8216;or&#8217; (|) returns a binary number with 1 at digits where at least one of the digits of the operands was 1:<\/p>\n<pre class=\"brush:py\">\r\nprint 0 & 1    # prints 1 (0001), since 0000 'and' 0001 => 0001\r\nprint 2 & 3    # prints 3 (0011), since 0010 'and' 0011 => 0011\r\nprint 2 & 7    # prints 7 (0111), since 0010 'and' 0111 => 0111 \r\nprint 15 & 10  # prints 15 (1111), since 1111 'and' 1010 => 1111  \r\n<\/pre>\n<p>Getting back to the example of geometry filters in rhinoscriptsyntax, this snippet returns the guids of both points and curves:<\/p>\n<pre class=\"brush:py\">\r\nguids = rs.ObjectsByType(rs.filter.point | rs.filter.curve)\r\n<\/pre>\n<p>What happens in the background is the following. The result of the combined filter is:<\/p>\n<pre class=\"brush:py\">\r\nfilter = rs.filter.point | rs.filter.curve\r\nprint filter  # prints 5 (0101), since 0001 'or' 0100 => 0101\r\n<\/pre>\n<p>Comparing this combined filter with the filter values of the different geometry types using bitwise &#8216;and&#8217; the function can figure out which types to include in the result:<\/p>\n<pre class=\"brush:py\">\r\ninclude_points   = False\r\ninclude_curves   = False\r\ninclude_surfaces = False\r\n\r\nif filter & rs.filter.point: \r\n    include_points = True\r\n\r\nif filter & rs.filter.curve: \r\n    include_curves = True\r\n\r\nif filter & rs.filter.surface: \r\n    include_surfaces = True\r\n\r\nprint include_points    # prints True\r\nprint include_curves    # prints True\r\nprint include_surfaces  # prints False\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Python has logical operators (like &#8216;and&#8217;) and bitwise operators (like &#8216;&#038;&#8217;). Bitwise operators are not that common in Python code, but they can be extremely useful in some cases. For example, in RhinoPython they are used to work with geometry type filters.<\/p>\n","protected":false},"author":11,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[10],"tags":[],"class_list":["post-1214","post","type-post","status-publish","format-standard","hentry","category-code"],"_links":{"self":[{"href":"https:\/\/block.arch.ethz.ch\/blog\/wp-json\/wp\/v2\/posts\/1214","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/block.arch.ethz.ch\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/block.arch.ethz.ch\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/block.arch.ethz.ch\/blog\/wp-json\/wp\/v2\/users\/11"}],"replies":[{"embeddable":true,"href":"https:\/\/block.arch.ethz.ch\/blog\/wp-json\/wp\/v2\/comments?post=1214"}],"version-history":[{"count":10,"href":"https:\/\/block.arch.ethz.ch\/blog\/wp-json\/wp\/v2\/posts\/1214\/revisions"}],"predecessor-version":[{"id":1224,"href":"https:\/\/block.arch.ethz.ch\/blog\/wp-json\/wp\/v2\/posts\/1214\/revisions\/1224"}],"wp:attachment":[{"href":"https:\/\/block.arch.ethz.ch\/blog\/wp-json\/wp\/v2\/media?parent=1214"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/block.arch.ethz.ch\/blog\/wp-json\/wp\/v2\/categories?post=1214"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/block.arch.ethz.ch\/blog\/wp-json\/wp\/v2\/tags?post=1214"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}