{"id":213,"date":"2004-11-20T07:56:00","date_gmt":"2004-11-20T14:56:00","guid":{"rendered":"http:\/\/kodegeek.com\/blog\/?p=213"},"modified":"2004-11-20T07:56:00","modified_gmt":"2004-11-20T14:56:00","slug":"echando-codigo-%c2%bfporque-usar-bigdecimal-para-calculos-financieros-y-no-double","status":"publish","type":"post","link":"http:\/\/kodegeek.com\/blog\/2004\/11\/20\/echando-codigo-%c2%bfporque-usar-bigdecimal-para-calculos-financieros-y-no-double\/","title":{"rendered":"Echando c\u00f3digo: \u00bfPorqu\u00e9 usar BigDecimal para c\u00e1lculos financieros y no Double?"},"content":{"rendered":"<p><img decoding=\"async\" src=\"http:\/\/java.sun.com\/im\/logo_java.gif\" \/><br \/>\n<br \/>La raz\u00f3n es simple: Java <span style=\"font-style: italic;\">no puede representar exactamente un n\u00famero como un double<\/span>, asi que si es necesario (por ejemplo para matem\u00e1tica financiera) es mejor utilizar la clase &#8216;<span style=\"font-family: courier new;\">Java.math.BigDecimal&#8217;<\/span>.<\/p>\n<p>Si bien la clase no es perfecta (es m\u00e1s dificil de usar que un simple n\u00famero y los c\u00e1lculos som m\u00e1s lentos que usando n\u00fameros regulares) si se necesita precisici\u00f3n entonces es la \u00fanica manera de hacerlo en Java (hay trucos trabajando con matem\u00e1tica entera, pero de nuevo yo pienso que estas librer\u00edas ya fueron codificadas por expertos en el \u00e1rea y en el futuro mejorar\u00e1n su desempe\u00f1o).<\/p>\n<p>El libro &#8216;Effective Java&#8217; (del cual ya habl\u00e9 en una oportunidad) presenta ejemplos concretos de porqu\u00e9 no hacerlo, y este tutorial de <a href=\"http:\/\/www.javaworld.com\/javaworld\/jw-06-2001\/jw-0601-cents.html\">JavaWorld<\/a> es bien completo adem\u00e1s.<\/p>\n<p>Como siempre, les dejo un peque\u00f1o pedazo de c\u00f3digo para que jueguen con \u00e9l. En este caso es el c\u00e1lculo del valor presente neto (NPV) en una clase ultra sencilla de Java:<\/p>\n<pre>\n<br \/>import java.math.BigDecimal;\n<br \/>\n<br \/>\/**\n<br \/> * This class shows how to use the BigDecimal class for numeric \n<br \/>calculation that require to be exact.\n<br \/> * This particular class implements the formula of present value. The \n<br \/>correct value was calculated using the\n<br \/> * OpenOffice function :NPV(rate, range1, range2, ...). Only showing \n<br \/>the first 20 decimals.\n<br \/> * @author Jose Vicente Nunez Zuleta (josevnz@yahoo.com)\n<br \/> * @version 0.1\n<br \/> * @see http:\/\/www.investopedia.com\/articles\/03\/101503.asp (check the \n<br \/>example here. Also the calculator shows the wrong values: 209.21, not \n<br \/>133.74)\n<br \/> * @see http:\/\/www.developer.com\/java\/other\/article.php\/631281\n<br \/> * @see http:\/\/www.developer.com\/java\/article.php\/788311\n<br \/> *\/\n<br \/>public final class PV {\n<br \/>\t\n<br \/>\tprivate static BigDecimal power(BigDecimal number, int power) {\n<br \/>\t\t\tBigDecimal powerc = number;\n<br \/>\t\t\tfor (int j=1; j < power; j++) {\n<br \/>\t\t\t\tpowerc = powerc.multiply(number);\n<br \/>\t\t\t}\n<br \/>\t\t\treturn powerc;\n<br \/>\t}\n<br \/>\tpublic static double regularNPV(double [] cashflows, double \n<br \/>discountRate) {\n<br \/>\t\tdouble pv = cashflows[0];\n<br \/>\t\tfor (int i=1; i < cashflows.length; i++) {\n<br \/>\t\t\tpv += cashflows[i] \/ Math.pow((1 + discountRate), i);\n<br \/>\t\t}\n<br \/>\t\treturn pv;\n<br \/>\t}\n<br \/>\t\n<br \/>\tpublic static BigDecimal correctNPV(BigDecimal [] cashflows, \n<br \/>BigDecimal discountRate) {\n<br \/>\t\tBigDecimal pv = cashflows[0];\n<br \/>\t\tfor (int i=1; i < cashflows.length; i++) {\n<br \/>\t\t\tpv = pv.add(cashflows[i].divide(power(discountRate.add(new \n<br \/>BigDecimal(\"1.0\")), i), BigDecimal.ROUND_HALF_EVEN));\n<br \/>\t\t}\n<br \/>\t\treturn pv;\n<br \/>\t}\n<br \/>\n<br \/>\tpublic static void main(String [] args) {\n<br \/>\n<br \/>\t\t\/\/ Calculation of the present value, \"traditional\" way\n<br \/>\t\tdouble [] cashflows     = { -1000.0f, 500.0f, 400.0f, 300.0f, 200.0f, \n<br \/>100.0f };\n<br \/>\t\tdouble discountRate     = 10.0f \/ 100.0f;\n<br \/>\t\tdouble pv = regularNPV(cashflows, discountRate);\n<br \/>\t\t\n<br \/>\t\tBigDecimal [] cashflows2 = new BigDecimal [6];\n<br \/>\t\tBigDecimal discountRate2 = new BigDecimal(\"0.1\");\n<br \/>\t\tcashflows2[0] = new BigDecimal(\"-1000.0\");\n<br \/>\t\tcashflows2[1] = new BigDecimal(\"500.0\");\n<br \/>\t\tcashflows2[2] = new BigDecimal(\"400.0\");\n<br \/>\t\tcashflows2[3] = new BigDecimal(\"300.0\");\n<br \/>\t\tcashflows2[4] = new BigDecimal(\"200.0\");\n<br \/>\t\tcashflows2[5] = new BigDecimal(\"100.0\");\n<br \/>\t\tBigDecimal pv2 = correctNPV(cashflows2, discountRate2);\n<br \/>\n<br \/>\t\tSystem.out.println(\"PV Theoric: $133.74645298694200000000\");\n<br \/>\t\tSystem.out.println(\"PV Regular: $\" + pv);\n<br \/>\t\tSystem.out.println(\"PV Proper:  $\" + pv2.toString());\n<br \/>\t}\n<br \/>}\n<br \/><\/pre>\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>La raz\u00f3n es simple: Java no puede representar exactamente un n\u00famero como un double, asi que si es necesario (por ejemplo para matem\u00e1tica financiera) es mejor utilizar la clase &#8216;Java.math.BigDecimal&#8217;. Si bien la clase no es perfecta (es m\u00e1s dificil de usar que un simple n\u00famero y los c\u00e1lculos som m\u00e1s lentos que usando n\u00fameros <a class=\"read-more\" href=\"http:\/\/kodegeek.com\/blog\/2004\/11\/20\/echando-codigo-%c2%bfporque-usar-bigdecimal-para-calculos-financieros-y-no-double\/\">[&hellip;]<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[],"tags":[],"_links":{"self":[{"href":"http:\/\/kodegeek.com\/blog\/wp-json\/wp\/v2\/posts\/213"}],"collection":[{"href":"http:\/\/kodegeek.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/kodegeek.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/kodegeek.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/kodegeek.com\/blog\/wp-json\/wp\/v2\/comments?post=213"}],"version-history":[{"count":0,"href":"http:\/\/kodegeek.com\/blog\/wp-json\/wp\/v2\/posts\/213\/revisions"}],"wp:attachment":[{"href":"http:\/\/kodegeek.com\/blog\/wp-json\/wp\/v2\/media?parent=213"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/kodegeek.com\/blog\/wp-json\/wp\/v2\/categories?post=213"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/kodegeek.com\/blog\/wp-json\/wp\/v2\/tags?post=213"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}