{"id":7597,"date":"2016-08-12T06:48:04","date_gmt":"2016-08-12T11:48:04","guid":{"rendered":"http:\/\/bobbeaty.com\/wp\/?p=7597"},"modified":"2016-12-24T06:14:26","modified_gmt":"2016-12-24T12:14:26","slug":"interesting-rounding-issue-in-clojure","status":"publish","type":"post","link":"https:\/\/bobbeaty.com\/wp\/archives\/7597","title":{"rendered":"Interesting Rounding Issue in Clojure"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/bobbeaty.com\/wp\/wp-content\/uploads\/2010\/04\/Clojure.jpg\" alt=\"Clojure.jpg\" title=\"Clojure.jpg\" border=\"0\" width=\"125\" height=\"125\" style=\"float:right;\" \/>We have a shared library that has a lot of really useful functions in it for all the apps we build, and one of the really useful things is to round to a fixed number of decimal places. Now, this isn't <em>Rocket Science<\/em>, but it is nice to have written <em>well<\/em> once, and then not have to mess with ever again.<\/p>\n<p>The trick is that you need it to be fast for all Clojure datatypes as well. And several of the more common implementations aren't very fast due to boxing and the overhead associated with that. So we made some pretty simple little functions:<\/p>\n<pre class=\"clojure\" style=\"font-family:monospace;\">  <span style=\"color: #66cc66;\">&#40;<\/span><span style=\"color: #b1b100;\">defn<\/span> to<span style=\"color: #66cc66;\">-<\/span>2dp\n    <span style=\"color: #ff0000;\">&quot;Function to simply resolve a number to a decimal (double), and then round\n    it to 2 DP and return it. Pretty simple, but very useful.&quot;<\/span>\n    <span style=\"color: #66cc66;\">&#91;<\/span>x<span style=\"color: #66cc66;\">&#93;<\/span>\n    <span style=\"color: #66cc66;\">&#40;<\/span><span style=\"color: #66cc66;\">\/<\/span> <span style=\"color: #66cc66;\">&#40;<\/span>math<span style=\"color: #66cc66;\">\/<\/span>round <span style=\"color: #66cc66;\">&#40;<\/span><span style=\"color: #66cc66;\">*<\/span> <span style=\"color: #cc66cc;\">100.0<\/span> <span style=\"color: #66cc66;\">&#40;<\/span>parse<span style=\"color: #66cc66;\">-<\/span>double x<span style=\"color: #66cc66;\">&#41;<\/span><span style=\"color: #66cc66;\">&#41;<\/span><span style=\"color: #66cc66;\">&#41;<\/span> <span style=\"color: #cc66cc;\">100.0<\/span><span style=\"color: #66cc66;\">&#41;<\/span><span style=\"color: #66cc66;\">&#41;<\/span>\n&nbsp;\n  <span style=\"color: #66cc66;\">&#40;<\/span><span style=\"color: #b1b100;\">defn<\/span> to<span style=\"color: #66cc66;\">-<\/span>3dp\n    <span style=\"color: #ff0000;\">&quot;Function to simply resolve a number to a decimal (double), and then round\n    it to 3 DP and return it. Pretty simple, but very useful.&quot;<\/span>\n    <span style=\"color: #66cc66;\">&#91;<\/span>x<span style=\"color: #66cc66;\">&#93;<\/span>\n    <span style=\"color: #66cc66;\">&#40;<\/span><span style=\"color: #66cc66;\">\/<\/span> <span style=\"color: #66cc66;\">&#40;<\/span>math<span style=\"color: #66cc66;\">\/<\/span>round <span style=\"color: #66cc66;\">&#40;<\/span><span style=\"color: #66cc66;\">*<\/span> <span style=\"color: #cc66cc;\">1000.0<\/span> <span style=\"color: #66cc66;\">&#40;<\/span>parse<span style=\"color: #66cc66;\">-<\/span>double x<span style=\"color: #66cc66;\">&#41;<\/span><span style=\"color: #66cc66;\">&#41;<\/span><span style=\"color: #66cc66;\">&#41;<\/span> <span style=\"color: #cc66cc;\">1000.0<\/span><span style=\"color: #66cc66;\">&#41;<\/span><span style=\"color: #66cc66;\">&#41;<\/span><\/pre>\n<p>but we had a problem. Some of the inputs gave us a lot of grief because of some nasty rounding. And it wasn't all values - it was just those values that had a hard time being expressed in the floating point format.<\/p>\n<p>The solution was to accept some of the inefficiency of rat eJVM <tt>BigDecimal<\/tt> and the advanced representation it had, and use that:<\/p>\n<pre class=\"clojure\" style=\"font-family:monospace;\">  <span style=\"color: #66cc66;\">&#40;<\/span><span style=\"color: #b1b100;\">defn<\/span> to<span style=\"color: #66cc66;\">-<\/span>2dp\n    <span style=\"color: #ff0000;\">&quot;Function to simply resolve a number to a decimal (double), and then round\n    it to 2 DP and return it. Pretty simple, but very useful.&quot;<\/span>\n    <span style=\"color: #66cc66;\">&#91;<\/span>x<span style=\"color: #66cc66;\">&#93;<\/span>\n    <span style=\"color: #66cc66;\">&#40;<\/span><span style=\"color: #66cc66;\">\/<\/span> <span style=\"color: #66cc66;\">&#40;<\/span>math<span style=\"color: #66cc66;\">\/<\/span>round <span style=\"color: #66cc66;\">&#40;<\/span><span style=\"color: #66cc66;\">*<\/span> <span style=\"color: #cc66cc;\">100.0<\/span> <span style=\"color: #66cc66;\">&#40;<\/span>bigdec <span style=\"color: #66cc66;\">&#40;<\/span>parse<span style=\"color: #66cc66;\">-<\/span>double x<span style=\"color: #66cc66;\">&#41;<\/span><span style=\"color: #66cc66;\">&#41;<\/span><span style=\"color: #66cc66;\">&#41;<\/span><span style=\"color: #66cc66;\">&#41;<\/span> <span style=\"color: #cc66cc;\">100.0<\/span><span style=\"color: #66cc66;\">&#41;<\/span><span style=\"color: #66cc66;\">&#41;<\/span>\n&nbsp;\n  <span style=\"color: #66cc66;\">&#40;<\/span><span style=\"color: #b1b100;\">defn<\/span> to<span style=\"color: #66cc66;\">-<\/span>3dp\n    <span style=\"color: #ff0000;\">&quot;Function to simply resolve a number to a decimal (double), and then round\n    it to 3 DP and return it. Pretty simple, but very useful.&quot;<\/span>\n    <span style=\"color: #66cc66;\">&#91;<\/span>x<span style=\"color: #66cc66;\">&#93;<\/span>\n    <span style=\"color: #66cc66;\">&#40;<\/span><span style=\"color: #66cc66;\">\/<\/span> <span style=\"color: #66cc66;\">&#40;<\/span>math<span style=\"color: #66cc66;\">\/<\/span>round <span style=\"color: #66cc66;\">&#40;<\/span><span style=\"color: #66cc66;\">*<\/span> <span style=\"color: #cc66cc;\">1000.0<\/span> <span style=\"color: #66cc66;\">&#40;<\/span>bigdec <span style=\"color: #66cc66;\">&#40;<\/span>parse<span style=\"color: #66cc66;\">-<\/span>double x<span style=\"color: #66cc66;\">&#41;<\/span><span style=\"color: #66cc66;\">&#41;<\/span><span style=\"color: #66cc66;\">&#41;<\/span><span style=\"color: #66cc66;\">&#41;<\/span> <span style=\"color: #cc66cc;\">1000.0<\/span><span style=\"color: #66cc66;\">&#41;<\/span><span style=\"color: #66cc66;\">&#41;<\/span><\/pre>\n<p>and then things settled down.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>We have a shared library that has a lot of really useful functions in it for all the apps we build, and one of the really useful things is to round to a fixed number of decimal places. Now, this isn&#8217;t Rocket Science, but it is nice to have written well once, and then not [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[11,6],"tags":[],"class_list":["post-7597","post","type-post","status-publish","format-standard","hentry","category-clojure-coding","category-cube-life"],"_links":{"self":[{"href":"https:\/\/bobbeaty.com\/wp\/wp-json\/wp\/v2\/posts\/7597","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/bobbeaty.com\/wp\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/bobbeaty.com\/wp\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/bobbeaty.com\/wp\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/bobbeaty.com\/wp\/wp-json\/wp\/v2\/comments?post=7597"}],"version-history":[{"count":2,"href":"https:\/\/bobbeaty.com\/wp\/wp-json\/wp\/v2\/posts\/7597\/revisions"}],"predecessor-version":[{"id":7599,"href":"https:\/\/bobbeaty.com\/wp\/wp-json\/wp\/v2\/posts\/7597\/revisions\/7599"}],"wp:attachment":[{"href":"https:\/\/bobbeaty.com\/wp\/wp-json\/wp\/v2\/media?parent=7597"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/bobbeaty.com\/wp\/wp-json\/wp\/v2\/categories?post=7597"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/bobbeaty.com\/wp\/wp-json\/wp\/v2\/tags?post=7597"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}