{"id":2424,"date":"2017-03-25T00:01:18","date_gmt":"2017-03-25T07:01:18","guid":{"rendered":"http:\/\/c-for-dummies.com\/blog\/?p=2424"},"modified":"2017-04-01T07:42:30","modified_gmt":"2017-04-01T14:42:30","slug":"from-decimal-to-roman","status":"publish","type":"post","link":"https:\/\/c-for-dummies.com\/blog\/?p=2424","title":{"rendered":"From Decimal to Roman"},"content":{"rendered":"<p>The C language lacks a <em>printf()<\/em> conversion character to display Roman numerals. Therefore, if your code requires input of a decimal value, say 266, and output of a Roman numeral value, which would be CCLXVI, you must craft your own function.<br \/>\n<!--more--><br \/>\nThe process isn&#8217;t that difficult, specifically when you don&#8217;t care about the reduced values IV, IX, XL, XC, CD, and CM. Forget that those abbreviations exist for a moment and concentrate on the problem: Take a decimal (<em>int<\/em>) value and peel out the Roman numeral digits in order, highest-to-lowest: M, D, C, L, X, V, and then I.<\/p>\n<p>The code is similar to the solution for the common &#8220;make change&#8221; programming puzzle. I presented that problem as an <a href=\"http:\/\/c-for-dummies.com\/blog\/?p=1083\">Exercise<\/a> back in December 2014, which is December MMXIIII. Or, if you abbreviate, it&#8217;s December MMXIV.<\/p>\n<p>Like the &#8220;make change&#8221; solution, to convert a decimal value to a Roman numeral string, you subtract high values from the input. Then you subtract smaller values on down, processing the number until it&#8217;s whittled to zero.<\/p>\n<p>My code starts with a <em>main()<\/em> function that obtains input in the range of 1 to 5000. You must ensure that the values are positive and not too big, though you can set any range you like to see how the code handles it.<\/p>\n<p>The <em>decimal2roman()<\/em> function performs the translation.<\/p>\n<pre class=\"screen\">\r\n#include &lt;stdio.h&gt;\r\n\r\n#define SIZE 20\r\n\r\nvoid decimal2roman(char *r,int v);\r\n\r\nint main()\r\n{\r\n    char roman[SIZE];\r\n    int value;\r\n\r\n    <span class=\"comments\">\/* get input *\/<\/span>\r\n    printf(\"Type an integer value: \");\r\n    scanf(\"%d\",&value);\r\n\r\n    <span class=\"comments\">\/* test range *\/<\/span>\r\n    if(value &lt; 1 || value &gt; 5000)\r\n    {\r\n        puts(\"Valid input is from 1 through 5000\");\r\n        return(1);\r\n    }\r\n\r\n    <span class=\"comments\">\/* translate and display results *\/<\/span>\r\n    decimal2roman(roman,value);\r\n    printf(\"The value %d is %s\\n\",value,roman);\r\n\r\n    return(0);\r\n}\r\n\r\nvoid decimal2roman(char *r,int v)\r\n{\r\n    int index = 0;\r\n\r\n    while(v)\r\n    {\r\n        if(v &gt;= 1000)\r\n        {\r\n            *(r+index) = 'M';\r\n            index++;\r\n            v -= 1000;\r\n        }\r\n        else if(v &gt;= 500)\r\n        {\r\n            *(r+index) = 'D';\r\n            index++;\r\n            v -= 500;\r\n        }\r\n        else if(v &gt;= 100)\r\n        {\r\n            *(r+index) = 'C';\r\n            index++;\r\n            v -= 100;\r\n        }\r\n        else if(v &gt;= 50)\r\n        {\r\n            *(r+index) = 'L';\r\n            index++;\r\n            v -= 50;\r\n        }\r\n        else if(v &gt;= 10)\r\n        {\r\n            *(r+index) = 'X';\r\n            index++;\r\n            v -= 10;\r\n        }\r\n        else if(v &gt;= 5)\r\n        {\r\n            *(r+index) = 'V';\r\n            index++;\r\n            v -= 5;\r\n        }\r\n        else\r\n        {\r\n            *(r+index) = 'I';\r\n            index++;\r\n            v--;\r\n        }\r\n        <span class=\"comments\">\/* prevent overflow *\/<\/span>\r\n        if(index == SIZE)\r\n            break;\r\n    }\r\n    <span class=\"comments\">\/* cap the string *\/<\/span>\r\n    *(r+index) = '\\0';\r\n}<\/pre>\n<p>The <em>decimal2roman()<\/em> function consists of a huge <em>if-else<\/em> structure. You can&#8217;t use a <em>switch-case<\/em> structure due to the comparisons required. A <em>while<\/em> loop monitors variable <code>v<\/code>, the decimal value passed to the function. The loop spins until <code>v<\/code> equals zero.<\/p>\n<p>Pointer <code>r<\/code> in the function references a string that contains the Roman numeral characters.<\/p>\n<p>At Line 36, if value <code>v<\/code> is greater than 1000, character <code>'M'<\/code> is inserted into the string. The string pointer is incremented, then 1000 is subtracted from <code>v<\/code>.<\/p>\n<p>Subsequent <em>else-if<\/em> tests peel out values 500, 100, 50, 10, 5, and finally 1. The <em>if-else<\/em> structure works as a filter, so that <code>v<\/code> only descends into the final statements once its value becomes small enough. All the time, string <code>r<\/code> is built up with Roman numerals in the proper order.<\/p>\n<p>A test at Line 79 ensures that the string doesn&#8217;t overflow, or contain more characters than allocated in the buffer. Then, finally, at Line 83, the string is capped with a null character, <code>'\\0'<\/code>, and the function returns.<\/p>\n<p>Here are some sample runs:<\/p>\n<pre><code>Type an integer value: 658\r\nThe value 658 is DCLVIII\r\n\r\nType an integer value: 1002\r\nThe value 1002 is MII\r\n\r\nType an integer value: 1234\r\nThe value 1234 is MCCXXXIIII<\/code><\/pre>\n<p>As you can see from the final output, the value IIII isn&#8217;t condensed to IV. That process requires more code, which I present in <a href=\"http:\/\/c-for-dummies.com\/blog\/?p=2430\">next week&#8217;s Lesson<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Just in time for your new printer that can chisel into marble, a function that translates decimal to Roman numerals. <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=2424\">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-2424","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\/2424","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=2424"}],"version-history":[{"count":3,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/2424\/revisions"}],"predecessor-version":[{"id":2457,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/2424\/revisions\/2457"}],"wp:attachment":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2424"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2424"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2424"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}