【问题标题】:Best Practice for financial calculations using JSTL/Tomcat [closed]使用 JSTL/Tomcat 进行财务计算的最佳实践 [关闭]
【发布时间】:2013-01-15 19:14:19
【问题描述】:

我正在使用 Tomcat/JSTL/MySQL/等构建一个新的电子商务平台。

我知道与使用浮点计算相关的各种问题 - 例如12.3456000000000789...我知道舍入与截断也可能是一个问题。

如果不将所有业务逻辑都转移到 Java 类中,那么在保持架构简单的同时对货币进行可靠计算的最佳方法是什么?

我对可能性的看法包括:

  • 隔离问题计算并单独处理
  • 将数字表示为多头并使用美分进行计算
  • 使用 BigDecimal 并在 Java 中进行所有计算
  • 尽可能将数字存储在字符串中
  • 使用

我可能不是第一个这样做的人。

最直接的方法是什么?

【问题讨论】:

  • 我听说 BigDecimal 是专门为此类事情设计的。不过我不是专家。
  • 通过互联网搜索。这个问题已经回答了:What Every Computer Scientist Should Know About Floating-Point Arithmetic。简短回答:使用BigDecimal
  • <fmt:formatNumber ..> 对视图很有帮助,因为大多数客户不会对看到超过 2 位小数感兴趣 ;) 此外,您可以在其中添加货币符号,这非常好。
  • 谢谢。我知道浮点数和 BigDecimal 的问题。我希望在留在 JSTL EL 中时有一种简单的方法来使用它。例如c:set var=... value=... type="java.math.BigDecimal" 然后有很好的对象可以使用。我知道这要求很多。鉴于 Web 应用程序的性质,JSTL 设计人员最好在...中构建一些东西。
  • 如果您的环境支持 EL 2.2,您可以在 EL 中调用 BigDecimal 特定的方法。对于其余部分,这个问题是题外话/非建设性的。尝试更强大的程序员.se,而不是基本上问“我知道除了 BigDecimal 没有其他方法,但还有其他方法吗?”。

标签: java jsp jstl decimal


【解决方案1】:

隔离问题计算并单独处理

没有答案。您使用的任何技术都将来自您列表中的其他地方。

将数字表示为多头并使用美分进行计算

可行但很笨拙,在金融领域中,有一小部分是有效的:例如,外汇。

使用 BigDecimal 并在 Java 中进行所有计算

这就是答案。更好的是,在数据库中进行计算。

尽可能将数字存储在字符串中

没有答案。您仍然需要计算,当您计算时,该技术将来自您列表中的其他地方。

使用

没有答案。您当然必须使用 formatNumber,但它没有说明您将如何计算。我不明白 c:set 与它有什么关系,它做了不同的事情。它不是 numberFormat 的替代品。

【讨论】:

    【解决方案2】:

    如果不将所有业务逻辑转移到 Java 类中,那么什么是 对货币进行可靠计算的最佳方法,同时 保持架构简单?

    选择简单或可靠 - 在这种情况下你不能同时拥有两者 - 至少不是那么简单。

    JSP 页面中的业务逻辑是一种非常糟糕的代码味道 - 在小型个人项目中已经够糟糕了,但是为什么要在“电子商务平台”中这样做呢?

    尽管您对此犹豫不决,但我建议您将所有业务逻辑从 JSP 移至适当的 Java 类。

    更好的是,鉴于您正在开发处理金融交易的软件,请帮您自己和您的潜在客户一个大忙,并聘请一位知道他们在做什么的程序员。

    我意识到这有点侮辱,但鉴于您明显缺乏对 Java 编程语言和一般体面编码实践的熟悉,您真的没有业务编写处理他人资金的商业软件。

    【讨论】:

    • 是的。有点侮辱。我正在构建一个快速原型并试图让它保持轻便......
    【解决方案3】:

    宾果游戏。我的问题根本不在EL。原来我不小心在数据库中有一些浮点字段。当我将它们改回小数时,一切都到位了。

    似乎如果你从 MySQL 中提取一个小数,你会得到一个 BigDecimal。所以这个词毕竟是有序的。

    感谢大家的意见。

    见:

    <c:set var="tests" value="123.45"/>
    <br>tests: ${tests} -- <%= pageContext.findAttribute("tests").getClass() %>
    
    <c:set var="testl" value="${3}"/>
    <br>testl: ${testl} -- <%= pageContext.findAttribute("testl").getClass() %>
    
    <c:set var="testd" value="${123.45}"/> 
    <br>testd: ${testd} -- <%= pageContext.findAttribute("testd").getClass() %>
    
    <c:set var="testbd" value="<%= new BigDecimal(\"123.45\") %>"/>
    <br>testbd: ${testbd} -- <%= pageContext.findAttribute("testbd").getClass() %>
    
    <c:set var="testbd" value="${testbd+1}"/>
    <br>testbd: ${testbd} -- <%= pageContext.findAttribute("testbd").getClass() %>
    
    <sql:query var="items">
    SELECT * FROM items WHERE itemid=?;
    <sql:param value="55" />
    </sql:query>
    <c:set var="testdb" value="${items.rows[0].price}"/>
    <br>testdb: ${testdb} -- <%= pageContext.findAttribute("testdb").getClass() %>
    
    <%-- output
    tests: 123.45 -- class java.lang.String 
    testl: 3 -- class java.lang.Long 
    testd: 123.45 -- class java.lang.Double 
    testbd: 123.45 -- class java.math.BigDecimal 
    testbd: 124.45 -- class java.math.BigDecimal 
    testdb: 129.95 -- class java.math.BigDecimal
    --%>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-11-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-03
      • 2011-04-11
      • 1970-01-01
      相关资源
      最近更新 更多