{"id":982,"date":"2015-05-10T09:20:15","date_gmt":"2015-05-10T13:20:15","guid":{"rendered":"http:\/\/springframework.guru\/?p=982"},"modified":"2019-06-16T13:21:16","modified_gmt":"2019-06-16T17:21:16","slug":"monetary-calculation-pitfalls","status":"publish","type":"post","link":"https:\/\/springframework.guru\/monetary-calculation-pitfalls\/","title":{"rendered":"Monetary Calculation Pitfalls"},"content":{"rendered":"<p>People expect computer programs to be accurate and precise when calculating numbers, and especially programs that perform monetary calculations and as a Java developer,\u00a0sooner or later you will need to deal with monetary calculations.<\/p>\n<p>You may be tempted to use the primitive types of\u00a0<code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">float<\/code>\u00a0or\u00a0<code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">double<\/code> for non-integer numbers. Both of these types support numbers with decimals. As we will see below, there are some significant pitfalls in using these primitive types for monetary calculations.<\/p>\n<h2>Monetary Calculations: Bad Examples<\/h2>\n<p>You have 1.55 $ and you bought a candy worth 35 \u00a2. How much is left with you?<\/p>\n<p>Let&#8217;s do the calculation in Java.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\">. . .\r\nfloat pocketMoney=1.55f;\r\nfloat price=.35f;\r\nSystem.out.println(pocketMoney - price);\r\n. . .\r\n<\/pre>\n<p>If you said 1.20 $, you are in for a surprise. The output is:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">1.1999999<\/pre>\n<p>Let us look at another example, this time using <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">double<\/code>. A product is priced 10 $. What is the price after adding 8.25 % tax to it?<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\">. . .\r\ndouble amount = 10.00;\r\ndouble tax = .0825;\r\ndouble taxAmount = amount * tax;\r\ndouble amountAfterTax = amount + taxAmount;\r\nSystem.out.println(\"Tax: \"+ taxAmount);\r\nSystem.out.println(\"Amount after tax: \" + amountAfterTax);\r\n. . .\r\n<\/pre>\n<p>The output is:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">Tax: 0.8250000000000001\r\nAmount after tax: 10.825\r\n<\/pre>\n<p>We again have some unexpected numbers. A simple multiplication &#8220;10.00 X .0825&#8221; is not giving us what we expected &#8220;0.825&#8221;.<\/p>\n<p>So what&#8217;s the problem? Why can\u2019t Java perform such simple calculations? The problem is not with Java but how floating point is defined in the <a title=\"IEEE Standard for Floating-Point Arithmetic (IEEE 754)\" href=\"http:\/\/en.wikipedia.org\/wiki\/IEEE_floating_point\" target=\"_blank\" rel=\"noopener noreferrer\">IEEE 754<\/a> standard based on which Java implements <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">float<\/code> and <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">double<\/code>. Floating points are designed to provide accurate approximations (<strong>but not exact results<\/strong>) quickly and it is impossible to exactly represent 0.1 (or any other negative power of ten) as a Java <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">float<\/code> or <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">double<\/code>.<\/p>\n<p>Without going into more details of binary floating point arithmetic, let\u2019s find out how to perform monetary calculations accurately in Java. A solution is to do everything using integral types (<code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">int<\/code> and <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">long<\/code>) and I have met several programmers advocating it. But then you will need to remember that &#8220;325&#8221; in your program is really &#8220;3.25&#8221; dollar. Also, how will you do percent calculations rounding to the nearest cent? This is when you should turn to the <a title=\"Class BigDecimal\" href=\"https:\/\/docs.oracle.com\/javase\/8\/docs\/api\/java\/math\/BigDecimal.html\" target=\"_blank\" rel=\"noopener noreferrer\">BigDecimal<\/a> class.<\/p>\n<h2>Monetary Calculations Using BigDecimal<\/h2>\n<p>The <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">BigDecimal<\/code> class is a part of the <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">java.math<\/code> package. For a decimal number, <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">BigDecimal<\/code> internally stores the unscaled value in a <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">BigInteger<\/code> and the decimal scale (digits to the right of the decimal point) in an <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">integer<\/code>. So, the internally used <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">BigInteger<\/code> allows <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">BigDecimal<\/code> to represent any number, however big it is (only limited to physical memory) and the integer allows accurate handling of the decimal scale.<\/p>\n<p>During addition and subtraction operations, <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">BigDecimal<\/code> expands the number with the smallest scale before performing the operation. This guarantees that the sum or difference is exact to the last digit. During multiplication, <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">BigDecimal<\/code> computes the sum of the numbers scale and based on it expands its decimal scale.\u00a0For division, <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">BigDecimal<\/code> expects that the result can be represented with a scale that is the difference between the scale of the dividend and divisor.<\/p>\n<p>To perform the arithmetic calculations, <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">BigDecimal<\/code> provides the <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">add()<\/code>, <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">subtract()<\/code>, <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">multiply()<\/code>, and <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">divide()<\/code> methods. Before we use these methods, we need to represent the numbers as <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">BigDecimal<\/code> objects. The<code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\"> BigDecimal<\/code> class contains 16 overloaded constructors but the one that you will use to represent a monetary value is <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">BigDecimal(String val)<\/code>. This is important because if you mistakenly use the one that accepts <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">double<\/code>, you will face same issues as you do while using <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">float<\/code> and <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">double<\/code>. This happens because the <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">float<\/code> or <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">double<\/code> parameter value will undergo loss of precision before you pass them to the constructor. On the other hand, when you use the <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">String<\/code> constructor, <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">BigDecimal<\/code> will represent exactly the number you pass to it.<\/p>\n<p>Let\u2019s now perform some <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">BigDecimal<\/code> calculations.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\">. . .\r\nBigDecimal num1 = new BigDecimal(\"2.5\");\r\nBigDecimal num2 = new BigDecimal(\"3.5\");\r\nSystem.out.println(\"BigDecimal Addition: \"+ num1.add(num2));\r\nSystem.out.println(\"BigDecimal Subtraction: \"+ num1.subtract(num2));\r\nSystem.out.println(\"BigDecimal Multiplication: \"+ num1.multiply(num2));\r\nSystem.out.println(\"BigDecimal Division: \"+ num1.divide(num2));\r\n. . .\r\n<\/pre>\n<p>In the example above, we created two <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">BigDecimal<\/code> numbers and called the the <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">add()<\/code>, <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">subtract()<\/code>, <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">multiply()<\/code>, and <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">divide()<\/code> methods to perform arithmetic calculations.<\/p>\n<p>The output is:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">BigDecimal Addition: 6.0\r\nBigDecimal Subtraction: -1.0\r\nBigDecimal Multiplication: 8.75\r\nException in thread \"main\" java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.\r\n\tat java.math.BigDecimal.divide(BigDecimal.java:1690)\r\n\tat prototype.CloneExample.main(CloneExample.java:24)\r\n<\/pre>\n<p>As we can see the addition, subtraction, and multiplication in lines 4-6 were done as expected but the division in line 7 resulted in an exception. This happened because what we have is a non-terminating decimal expansion &#8220;2.5\/3.5 = 0.7142857142857. . . . .&#8221;. As mentioned earlier, for division <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">BigDecimal<\/code> expects that the result can be represented with a scale that is the difference between the scale of the dividend and divisor. Else, the JavaDoc says <em>&#8220;. . .if the exact quotient cannot be represented (because it has a non-terminating decimal expansion) an ArithmeticException is thrown&#8221;<\/em>&#8211; and hence the exception thrown in line 7.<\/p>\n<p>To avoid such exceptions, always set a resulting scale and a rounding mode during division by using the overloaded <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">divide(BigDecimal divisor, int scale, RoundingMode roundingMode)<\/code> method. In this method, the first parameter is the <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">BigDecimal<\/code> divisor. The second parameter specifies the decimal scale and the third an enumeration value of the <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">RoundingMode<\/code> enum. This enum, introduced in Java SE 6, provides eight different types of rounding modes whose descriptions with examples are available <a title=\"Enum RoundingMode\" href=\"https:\/\/docs.oracle.com\/javase\/8\/docs\/api\/java\/math\/RoundingMode.html\" target=\"_blank\" rel=\"noopener noreferrer\">here<\/a>.<\/p>\n<p><strong>Note<\/strong>: <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">BigDecimal<\/code> itself have integer fields to represent rounding modes, but they are now obsolete. Ensure that you instead use the <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">RoundingMode<\/code> enum for rounding modes in calculations.<\/p>\n<p>To display <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">BigDecimal<\/code> numbers, you can set the scale and rounding mode with the <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">BigDecimal.setScale(scale, roundingMode)<\/code> method.<\/p>\n<p>Now, the question is- Which rounding mode should I use for monetary calculations? The answer is, there is &#8220;no specific&#8221; mode. It depends on the application requirements and any legal contracts that your application must conform with. For example, it is common to use <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">RoundingMode.HALF_UP<\/code> for tax calculations. If you are selling a product and want to round in favor of the customer, use <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">RoundingMode.CEILING<\/code>. If you are not sure, go for <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">RoundingMode.HALF_EVEN<\/code>. This rounding mode, also known as <em>&#8220;Banker&#8217;s rounding&#8221;<\/em>, when applied repeatedly over a sequence of calculations statistically minimizes cumulative error.<\/p>\n<p>Let\u2019s now write some code to perform some monetary calculations using <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">BigDecimal<\/code>.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\">package guru.springframework.blog.monetarycalculations;\r\n\r\nimport java.math.BigDecimal;\r\nimport java.math.RoundingMode;\r\n\r\n\r\npublic class BigDecimalCalc {\r\n\r\n    public void calculate(String param1, String param2){\r\n        System.out.println(\"--------------------calculate-----------------------\");\r\n        BigDecimal num1=new BigDecimal(param1);\r\n        BigDecimal num2=new BigDecimal(param2);\r\n        System.out.println(\"num1: \"+num1+\" num2: \"+ num2);\r\n        System.out.println(\"BigDecimal Addition: \"+num1.add(num2));\r\n        System.out.println(\"BigDecimal Subtraction: \" + num1.subtract(num2));\r\n        System.out.println(\"BigDecimal Multiplication: \"+num1.multiply(num2));\r\n    }\r\n\r\n\r\n    public  void divideWithScaleRounding(String param1, String param2){\r\n        System.out.println(\"--------------------divisionWithScaleRounding-----------------------\");\r\n\r\n        \/*Setting scale and rounding mode for division using overloaded divide(BigDecimal divisor, int scale, RoundingMode roundingMode) *\/\r\n        BigDecimal num1=new BigDecimal(param1);\r\n        BigDecimal num2=new BigDecimal(param2);\r\n        System.out.println(\"num1: \"+num1+\" num2: \"+ num2);\r\n        System.out.println(\"BigDecimal Division with overloaded divide(): \" + num1.divide(num2, 4, RoundingMode.HALF_EVEN));\r\n    }\r\n\r\n    public void calculateTax(String amount, String tax){\r\n        System.out.println(\"--------------------calculateTax-----------------------\");\r\n        BigDecimal bdAmount = new BigDecimal(amount);\r\n        BigDecimal bdTax = new BigDecimal(tax);\r\n        BigDecimal taxAmount = bdAmount.multiply(bdTax);\r\n        \/*Setting scale and rounding mode using setScale() *\/\r\n        taxAmount = taxAmount.setScale(2, RoundingMode.HALF_UP);\r\n        BigDecimal finalAmount = bdAmount.add(taxAmount);\r\n        finalAmount = finalAmount.setScale(2, RoundingMode.HALF_UP);\r\n\r\n        System.out.println(\"Amount : \" + bdAmount);\r\n        System.out.println(\"Tax : \" + taxAmount);\r\n        System.out.println(\"Amount after tax: \" + finalAmount);\r\n\r\n    }\r\n}\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p>In the example above, we first wrote a <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">calculate()<\/code> method that accepts two <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">String<\/code> parameters. In lines 13-14 we converted them into <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">BigDecimal<\/code>. In lines 16-18 we performed addition, subtraction, and multiplication operations on the numbers. Next, we wrote a <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">divideWithScaleRounding()<\/code> method that also accepts two <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">String<\/code> parameters that we converted to <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">BigDecimal<\/code> in line 26-27. In line 29, we performed a division with a scale 4 and a rounding mode, <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">RoundingMode.HALF_EVEN<\/code>. Then, we wrote a <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">calculateTax()<\/code> method that accepts a monetary amount and a tax as <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">String<\/code> objects. After converting the parameters to <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">BigDecimal<\/code>, we calculated the tax amount in line 36. To display the tax amount with a scale 2 and a rounding mode <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">RoundingMode.HALF_UP<\/code>, we called the <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">setScale()<\/code> method in line 38. Similarly, we calculated the final amount and set its scale and rounding mode in lines 39-40. To test our example, let&#8217;s write this unit test.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\">package guru.springframework.blog.monetarycalculations;\r\n\r\nimport org.junit.Test;\r\n\r\n\r\npublic class BigDecimalCalcTest {\r\n\r\n    @Test\r\n    public void testCalculate() throws Exception {\r\n        new BigDecimalCalc().calculate(\"4.0\", \"2.0\");\r\n    }\r\n\r\n    @Test\r\n    public void testDivideWithScaleRounding() throws Exception {\r\n        new BigDecimalCalc().divideWithScaleRounding(\"2.5\", \"3.5\");\r\n    }\r\n\r\n    @Test\r\n    public void testCalculateTax() throws Exception {\r\n        new BigDecimalCalc().calculateTax(\"10.00\", \".0825\");\r\n    }\r\n}\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p>The output is:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">  .   ____          _            __ _ _\r\n \/\\\\ \/ ___'_ __ _ _(_)_ __  __ _ \\ \\ \\ \\\r\n( ( )\\___ | '_ | '_| | '_ \\\/ _` | \\ \\ \\ \\\r\n \\\\\/  ___)| |_)| | | | | || (_| |  ) ) ) )\r\n  '  |____| .__|_| |_|_| |_\\__, | \/ \/ \/ \/\r\n =========|_|==============|___\/=\/_\/_\/_\/\r\n :: Spring Boot ::        (v1.2.3.RELEASE)\r\n\r\nRunning guru.springframework.blog.monetarycalculations.BigDecimalCalcTest\r\n--------------------divisionWithScaleRounding-----------------------\r\nnum1: 2.5 num2: 3.5\r\nBigDecimal Division with overloaded divide(): 0.7143\r\n--------------------calculate-----------------------\r\nnum1: 4.0 num2: 2.0\r\nBigDecimal Addition: 6.0\r\nBigDecimal Subtraction: 2.0\r\nBigDecimal Multiplication: 8.00\r\n--------------------calculateTax-----------------------\r\nAmount : 10.00\r\nTax : 0.83\r\nAmount after tax: 10.83\r\nTests run: 3, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.011 sec - in guru.springframework.blog.monetarycalculations.BigDecimalCalcTest\r\n<\/pre>\n<p>In the output above, observe how <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">BigDecimal<\/code> performed the division and displayed monetary amounts with the specified scale and rounding mode. Using this example, go ahead and experiment with different sets of monetary values, scales, and rounding modes.<\/p>\n<h2>Summary<\/h2>\n<p>While float and double are natural choices for scientific, statistical and engineering calculations, <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">BigDecimal<\/code> is the ideal choice when it comes to monetary calculations. But, the precision and accuracy of <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">BigDecimal<\/code> comes with a price- and it is performance. However, if we require completely accurate monetary calculations, sacrifice of some performance is acceptable.<br \/>\nOn an ending note, keep an eye on <a href=\"https:\/\/jcp.org\/en\/jsr\/detail?id=354\">JSR 354: Money and Currency API<\/a>, which is planned to be included in Java 9. A part of this API is designed to support complex monetary calculation rules including calculation and display precisions. It will\u00a0be interesting to see if this API could change how we count our money in future.<\/p>\n<h2>Get The\u00a0Code<\/h2>\n<p>I&#8217;ve committed the source code for this post to GitHub. It is a Maven project which you can download and build. If you wish to learn more about the Spring Framework, I have a free introduction to the Spring tutorial. You can sign up for this tutorial in the section below.<\/p>\n\r\n\t<div class=\"df_call_to_action df_content_element cta_square\"  data-cta-class=\"normal\" data-cta-bg-color=\"#0F0F0F\" data-cta-border-color=\"#0F0F0F\">\r\n\t    <div class=\"cta_wrapper\">\r\n\t    \t<div class=\"cta_header\"><h3 style=\"color:#6cb44a !important;\">Source Code<\/h3><\/div>\r\n\t\t    <div class=\"cta_content\">The source code for this post is available on GitHub. You can download it <a title=\"Testing Spring Integration Gateways\" href=\"https:\/\/github.com\/springframeworkguru\/blogposts\" target=\"_blank\" rel=\"noopener noreferrer\">here<\/a>.<\/div>\r\n\t    <\/div>\r\n\t     \r\n\t<\/div>\r\n\n<h1 style=\"margin-top: 15px;\"><\/h1>\n","protected":false},"excerpt":{"rendered":"<p>People expect computer programs to be accurate and precise when calculating numbers, and especially programs that perform monetary calculations and as a Java developer,\u00a0sooner or later you will need to deal with monetary calculations. You may be tempted to use the primitive types of\u00a0float\u00a0or\u00a0double for non-integer numbers. Both of these types support numbers with decimals. [&hellip;]<a href=\"https:\/\/springframework.guru\/monetary-calculation-pitfalls\/\" class=\"df-link-excerpt\">Continue reading<\/a><\/p>\n","protected":false},"author":1,"featured_media":4592,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_lmt_disableupdate":"","_lmt_disable":"","_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_uf_show_specific_survey":0,"_uf_disable_surveys":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"Monetary Calculation Pitfalls in Java http:\/\/wp.me\/p5BZrZ-fQ #java","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","enabled":false},"version":2}},"categories":[20],"tags":[84,27],"class_list":["post-982","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-java","tag-bigdecimal","tag-java"],"jetpack_publicize_connections":[],"aioseo_notices":[],"modified_by":"Simanta","jetpack_sharing_enabled":true,"jetpack_featured_media_url":"https:\/\/springframework.guru\/wp-content\/uploads\/2015\/03\/Banner560x292_07web.jpg","jetpack_shortlink":"https:\/\/wp.me\/p5BZrZ-fQ","_links":{"self":[{"href":"https:\/\/springframework.guru\/wp-json\/wp\/v2\/posts\/982"}],"collection":[{"href":"https:\/\/springframework.guru\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/springframework.guru\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/springframework.guru\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/springframework.guru\/wp-json\/wp\/v2\/comments?post=982"}],"version-history":[{"count":10,"href":"https:\/\/springframework.guru\/wp-json\/wp\/v2\/posts\/982\/revisions"}],"predecessor-version":[{"id":5616,"href":"https:\/\/springframework.guru\/wp-json\/wp\/v2\/posts\/982\/revisions\/5616"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/springframework.guru\/wp-json\/wp\/v2\/media\/4592"}],"wp:attachment":[{"href":"https:\/\/springframework.guru\/wp-json\/wp\/v2\/media?parent=982"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/springframework.guru\/wp-json\/wp\/v2\/categories?post=982"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/springframework.guru\/wp-json\/wp\/v2\/tags?post=982"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}