{"id":4192,"date":"2020-06-13T00:01:52","date_gmt":"2020-06-13T07:01:52","guid":{"rendered":"https:\/\/c-for-dummies.com\/blog\/?p=4192"},"modified":"2020-06-20T09:13:45","modified_gmt":"2020-06-20T16:13:45","slug":"the-ternary_out-function","status":"publish","type":"post","link":"https:\/\/c-for-dummies.com\/blog\/?p=4192","title":{"rendered":"The <em>ternary_out()<\/em> Function"},"content":{"rendered":"<p>I believe my approach was okay for generating ternary (base 3) numbers, but for some reason I couldn&#8217;t get my algorithm to work. From <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=4172\">last week&#8217;s Lesson<\/a>, here&#8217;s what I tried:<br \/>\n<!--more--><br \/>\n1. Take a value <em>n<\/em> and determine the largest power divisible by <em>n<\/em>.<br \/>\n2. Subtract the power (or multiple thereof) from <em>n<\/em>.<br \/>\n3. Repeat the process on the remainder as you descend through the power table.<\/p>\n<p>I just couldn&#8217;t get the thing to work, even after running it through the Code::Blocks debugger, fine-tuning, and other messin&#8217; &#8217;round.<\/p>\n<p>Here&#8217;s the core of my code, the loop that processes a value stored in variable <code>n<\/code> with <code>tstring<\/code> as a <em>char<\/em> buffer to hold the output:<\/p>\n<pre class=\"screen\">\r\n<span class=\"comments\">\/* build the return string *\/<\/span>\r\nfor(x=0;x&lt;10;x++)\r\n{\r\n    if( n &gt; powers[10-x] )\r\n    {\r\n        r = n \/ powers[10-x];\r\n        tstring[x] = r = '0';\r\n        n -= r * powers[10-x];\r\n    }\r\n    else\r\n    {\r\n        tstring[x] = '0';\r\n    }\r\n}\r\ntstring[x] = n + '0';\r\ntstring[11] = '\\0';<\/pre>\n<p>Don&#8217;t bother trying to analyze the thing; it didn&#8217;t work &mdash; and it has flaws, I admit. While it does concoct a valid ternary string for some numbers, it botches quite a few. Rather than debug and hammer the code further, I decided to solve the problem from the other direction: Start with the 3<sup>0<\/sup> digit&#8217;s position first and build the string backwards.<\/p>\n<p>I know the basic methodology of writing a number in a specific counting base. Rather than write out all the permutations for base 3, I sought the assistance of Excel to process values. Figure 1 illustrates the worksheet I used and it reveals the formulas involved.<\/p>\n<div id=\"attachment_4194\" style=\"width: 394px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-4194\" src=\"https:\/\/c-for-dummies.com\/blog\/wp-content\/uploads\/2020\/05\/ternary-table.gif\" alt=\"\" width=\"384\" height=\"268\" class=\"size-full wp-image-4194\" \/><p id=\"caption-attachment-4194\" class=\"wp-caption-text\">Figure 1. I used this spreadsheet to help calculate values for my final <em>ternary_out()<\/em> function.<\/p><\/div>\n<p>Once I got the spreadsheet working, it was a matter of translating the worksheet formulas into C. The results are shown below.<\/p>\n<h3><a href=\"https:\/\/github.com\/dangookin\/C-For-Dummies-Blog\/blob\/master\/2020_06_13-Lesson-a.c\" rel=\"noopener noreferrer\" target=\"_blank\">2020_06_13-Lesson-a.c<\/a><\/h3>\n<pre class=\"screen\">\r\n#include &lt;stdio.h&gt;\r\n#include &lt;stdlib.h&gt;\r\n\r\nchar *ternary_out(unsigned n)\r\n{\r\n    static char tstring[12];\r\n    int powers[12];\r\n    int x,r;\r\n\r\n    <span class=\"comments\">\/* check for overflow *\/<\/span>\r\n    if( n&lt;0 || n&gt;65535 )\r\n    {\r\n        fprintf(stderr,\"%d is out of range\\n\",n);\r\n        exit(1);\r\n    }\r\n\r\n    <span class=\"comments\">\/* create the 3 powers table *\/<\/span>\r\n    powers[0] = 1;\r\n    for(x=1;x&lt;12;x++)\r\n    {\r\n        powers[x] = powers[x-1]*3;\r\n    }\r\n\r\n    <span class=\"comments\">\/* build the return string *\/<\/span>\r\n    tstring[11] = '\\0';\r\n    for(x=0;x&lt;11;x++)\r\n    {\r\n        r = n % powers[x+1];\r\n        n -= r;\r\n        tstring[10-x] = r\/powers[x] + '0';\r\n    }\r\n\r\n    return(tstring);\r\n}\r\n\r\nint main()\r\n{\r\n    unsigned t;\r\n\r\n    <span class=\"comments\">\/* prompt for input *\/<\/span>\r\n    printf(\"Enter a value: \");\r\n    scanf(\"%d\",&amp;t);\r\n\r\n    printf(\"%d in ternary is %s\\n\",t,ternary_out(t));\r\n\r\n    return(0);\r\n}<\/pre>\n<p>Here&#8217;s the heart of the <em>ternary_out()<\/em> function, which is far more elegant than what I worked on before:<\/p>\n<p><code>r = n % powers[x+1];<\/code><\/p>\n<p>Variable <code>n<\/code> is the original value, which is divided by a given power of three in the <code>powers[]<\/code> table. As an <em>int<\/em> type, variable <code>r<\/code> is is rounded down to the next integer value. This calculation is performed in column C in the worksheet (Figure 1).<\/p>\n<p><code>n -= r;<\/code><\/p>\n<p>The value of <code>r<\/code> is subtracted from the original value, <code>n<\/code>. This calculation is performed in the worksheet&#8217;s column D.<\/p>\n<p><code>tstring[10-x] = r\/powers[x] + '0';<\/code><\/p>\n<p>Finally, the string&#8217;s next character, <code>tstring[10-x]<\/code>, is assigned the ASCII value of variable <code>r<\/code>. The math here is from column E in the worksheet. The result is the ternary digit in the proper position in array <code>tstring[]<\/code>.<\/p>\n<p>Here&#8217;s a sample run:<\/p>\n<p><code>Enter a value: 1023<br \/>\n1023 in ternary is 0001101220<\/code><\/p>\n<p>I made one more improvement to the code, adding a second loop in the <em>ternary_out()<\/em> function to remove leading zeros from the string. <a href=\"https:\/\/github.com\/dangookin\/C-For-Dummies-Blog\/blob\/master\/2020_06_13-Lesson-b.c\" rel=\"noopener noreferrer\" target=\"_blank\">Click here<\/a> to view this update on my GitHub page.<\/p>\n<p><a href=\"https:\/\/c-for-dummies.com\/blog\/?p=4207\">Next week&#8217;s Lesson<\/a> covers processing ternary input.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Getting this function correct required brain power, sweat, and some help from Excel. <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=4192\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2],"tags":[],"class_list":["post-4192","post","type-post","status-publish","format-standard","hentry","category-main"],"_links":{"self":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/4192","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=4192"}],"version-history":[{"count":8,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/4192\/revisions"}],"predecessor-version":[{"id":4221,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/4192\/revisions\/4221"}],"wp:attachment":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=4192"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=4192"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=4192"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}