{"id":32,"date":"2009-02-07T01:24:34","date_gmt":"2009-02-07T09:24:34","guid":{"rendered":"http:\/\/porkrind.org\/missives2\/?p=32"},"modified":"2023-03-01T13:41:01","modified_gmt":"2023-03-01T21:41:01","slug":"pc-perl-calculator","status":"publish","type":"post","link":"https:\/\/porkrind.org\/missives\/pc-perl-calculator\/","title":{"rendered":"PC &#8211; Perl Calculator"},"content":{"rendered":"<h1>History<\/h1>\n<p>For years I was GUI calculator fanatic. Desperately searching for that perfect calculator that did all the things I wanted it to do. I wanted a programmers calculator that did hex and binary operations and didn\u2019t treat them as second class citizens. I used PCalc on the Mac for a while, and I even liked the built in Windows 95 calculator (that was the last time I had a dedicated Windows machine for working). But I was still left wanting.<\/p>\n<p>At some point I decided to write my own. My idea was that I wanted a text entry box where the equation you were typing would go. Then you could edit the text and produce a new result without retyping the whole thing. I only got as far as being able to parse the text and convert it to reverse polish for easy evaluation before I gave up. But I kept the idea in the back of my mind for years.<\/p>\n<p>At some point the idea morphed and I realized I didn\u2019t need any of the GUI buttons to click on when I always had a perfectly good keyboard sitting in front of me. I looked into bc and dc but they were both too complex for me. Finally one day it hit me that Perl\u2019s eval() was really what I wanted. And so \u201c<code>pc\u201d<\/code>, Perl Calc, was born.<\/p>\n<p><code>pc<\/code> started of very simple:<\/p>\n<pre><code class=\"language-perl\">#!\/usr\/bin\/perl\n\nwhile (&lt;&gt;) {\n    $a = eval($_);\n    printf(\"%d 0x%x 0%o %f\\n\",$a,$a,$a,$a);\n}\n<\/code><\/pre>\n<p>But it has now grown many features over the years designed to make my life more pleasant.<\/p>\n<h1>Getting PC<\/h1>\n<p>You can <a href=\"https:\/\/raw.github.com\/caldwell\/pc\/master\/pc\">download it here<\/a> or you can check it out from darcs like this:<\/p>\n<p><del><code>darcs get http:\/\/porkrind.org\/pc<\/code><\/del><\/p>\n<p><em>Edit (2013-05-30)<\/em>: I am no longer using darcs for this project. It is <a href=\"https:\/\/github.com\/caldwell\/pc\">now available on github<\/a>.<\/p>\n<p>You can give it input one of 2 ways: from the command line (this way you get all the editing and history niceties of your shell), or by running with no command line and typing into its stdin (this way you don\u2019t have to quote characters your shell would like to steal).<\/p>\n<h1>How to use pc<\/h1>\n<h2>The basics<\/h2>\n<pre><code class=\"language-bash\">$ pc 11+3\n14 0xe 016\n<\/code><\/pre>\n<p>The first number is the integer result, followed by the hex and octal representations. Simple enough.<\/p>\n<h2>Order of operations<\/h2>\n<p>This shows that <code>pc<\/code> uses Perl\u2019s order of operations (operator precedence if you are in a programming mood):<\/p>\n<pre><code class=\"language-shell\">$ pc 1+3*2\n7 0x7 07\n<\/code><\/pre>\n<h2>ASCII<\/h2>\n<pre><code class=\"language-bash\">$ pc 1+3*20\n61 0x3d 075 '='\n<\/code><\/pre>\n<p>Here we see an extra field was printed. In this case <code>pc<\/code> detected the final integer value was in the ASCII range and printed the character represented by the value 61, an equal sign.<\/p>\n<h2>Bitwise Operations<\/h2>\n<p>We also get Perl (and C) style bitwise operators:<\/p>\n<pre><code class=\"language-bash\">$ pc '1+3*20&lt;&lt;2 &amp; 0xff'\n244 0xf4 0364\n<\/code><\/pre>\n<p>Also notice that we had to quote it since (a) I put a space in the expression and (b) I used the \u2018&lt;\u2019 and \u2018&amp;\u2019 characters which mean something to the shell.<\/p>\n<h2>Floating point<\/h2>\n<p>Of course it\u2019s not restricted to only integers, it can handle floats too:<\/p>\n<pre><code class=\"language-shell\">$ pc 1+3*20\/55\n2 0x2 02 2.0909090909090 23\/11\n<\/code><\/pre>\n<p>You\u2019ll notice it shows the result of the floating point math <em>in addition to<\/em> the integer math.<\/p>\n<h2>Fractions<\/h2>\n<p>You might have noticed a fraction in the output of the previous example. <code>pc<\/code> uses Perl\u2019s \u201cbigrat\u201d library to do fractions:<\/p>\n<pre><code class=\"language-shell\">$ pc 3\/4+1\/2\n0 0x0 01 1.25 5\/4\n<\/code><\/pre>\n<h2>Human readable<\/h2>\n<pre><code class=\"language-shell\">$ pc 1000*2000\n2,000,000 2000000 0x1e,8480 0x1e8480 07502200 1.90MB\n<\/code><\/pre>\n<p>You\u2019ll notice that the integer and hex results are printed twice\u2014one with commas and one without. The one with commas is so that you the human can read the output easily. The one without commas is for copying and pasting. You should also notice that <code>pc<\/code> helpfully told you the number was 1.90MB. If a number is bigger than 1024 (1KB) it will print it in human readable byte quantity.<\/p>\n<h2>Power of 2 magnitude suffixes<\/h2>\n<p>It also accepts magnitude suffixes on the input:<\/p>\n<pre><code class=\"language-bash\">$ pc 16m\n16,777,216 16777216 0x100,0000 0x1000000 0100000000 16MB\n<\/code><\/pre>\n<p>The following suffixes are allowed: kmgtpezy (lowercase, no b). Note that the human readable output \u201c16MB\u201d doesn\u2019t have a decimal point. It will remove the decimal point if the number is <em>exactly<\/em> that value. So:<\/p>\n<pre><code class=\"language-bash\">$ pc 16m+1\n16,777,217 16777217 0x100,0001 0x1000001 0100000001 16.0MB\n<\/code><\/pre>\n<p>Since \u201c16.0MB\u201d has a decimal point, we know the value isn\u2019t exactly 16 megabytes.<\/p>\n<h2>Large numbers<\/h2>\n<p><code>pc<\/code> uses Perl\u2019s bigint so that it can handle numbers bigger than 32 bits:<\/p>\n<pre><code class=\"language-bash\">$ pc '&lt;&lt;40'\n1,099,511,627,776 1099511627776 0x100,0000,0000 0x10000000000 020000000000000 1TB\n<\/code><\/pre>\n<h2>Random Perl code<\/h2>\n<pre><code class=\"language-bash\">$ pc 'ord(\"a\")'\n0x61 0141 97 'a'\n<\/code><\/pre>\n<p>Since <code>pc<\/code> uses Perl\u2019s eval you can do arbitrary perl code too. Though frankly the only thing I\u2019ve ever used is <code>ord()<\/code>.<\/p>\n<h1>Conclusion<\/h1>\n<p>So there you have it. It\u2019s designed to give you all the output you ever could want without having to memorize any stupid command line switches. There are none, in fact. It also doesn\u2019t overload you with redundant data. If the floating point answer is the same as the integer answer then it doesn\u2019t show it to you. Same with the fractions.<\/p>\n<p>So, if you read this far, <a href=\"https:\/\/raw.github.com\/caldwell\/pc\/master\/pc\">go get it already!<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>For years I was  GUI calculator fanatic. Desperately searching for that perfect calculator that did all the things I wanted it to do&#8230; At some point I decided to write my own. Finally one day it hit me that Perl&#8217;s eval() was really what I wanted. And so &#8220;<code>pc<\/code>&#8220;, Perl Calc, was born.<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[3],"tags":[12],"class_list":["post-32","post","type-post","status-publish","format-standard","hentry","category-software","tag-perl"],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/porkrind.org\/missives\/wp-json\/wp\/v2\/posts\/32","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/porkrind.org\/missives\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/porkrind.org\/missives\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/porkrind.org\/missives\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/porkrind.org\/missives\/wp-json\/wp\/v2\/comments?post=32"}],"version-history":[{"count":16,"href":"https:\/\/porkrind.org\/missives\/wp-json\/wp\/v2\/posts\/32\/revisions"}],"predecessor-version":[{"id":737,"href":"https:\/\/porkrind.org\/missives\/wp-json\/wp\/v2\/posts\/32\/revisions\/737"}],"wp:attachment":[{"href":"https:\/\/porkrind.org\/missives\/wp-json\/wp\/v2\/media?parent=32"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/porkrind.org\/missives\/wp-json\/wp\/v2\/categories?post=32"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/porkrind.org\/missives\/wp-json\/wp\/v2\/tags?post=32"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}