4

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

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

在不将所有业务逻辑移入 Java 类的情况下,在保持架构简单的同时对货币进行可靠计算的最佳方法是什么?

我对可能性的想法包括:

  • 隔离问题计算并单独处理
  • 将数字表示为多头并使用美分进行计算
  • 使用 BigDecimal 并在 Java 中进行所有计算
  • 尽可能将数字存储在字符串中
  • 使用 <fmt:formatNumber var="... 而不是 <c:set var="...

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

最直接的方法是什么?

4

3 回答 3

3

隔离问题计算并单独处理

不是答案。无论您使用什么技术,都将来自您列表中的其他地方。

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

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

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

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

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

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

使用 <fmt:formatNumber var="... 而不是 <c:set var="...

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

于 2013-01-15T23:14:20.030 回答
0

在不将所有业务逻辑移入 Java 类的情况下,在保持架构简单的同时对货币进行可靠计算的最佳方法是什么?

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

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

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

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

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

于 2013-01-16T03:27:07.063 回答
0

答对了。我的问题根本不在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
--%>
于 2013-01-16T06:29:23.680 回答