2013-04-26 127 views
1

我正在尝试对JAVA + SQL中精确计算的选项建立一些简明概述。到目前为止,我已经找到以下选项:Java精确计算 - 使用选项

  1. 使用双打接受他们的缺点,没有去。在复杂的公式使用它们
  2. 使用BigDecimals的
    • 对我来说是有问题的
  3. 使用的String.format/Decimal.format圆双打
    • 我需要四舍五入每个变量式或只是结果得到BigDecimal精度?
    • 这怎么调整?
  4. 使用SQL中的计算字段选项。
    • 的缺点是,我需要动态SQL从不同的表中取出数据+计算上的其他计算领域和领域将变得混乱

任何其他的选择吗?

问题声明: 我需要精确的财务计算,其中涉及使用非常大(十亿)和非常小的数字(0.0000004321),并且还将彼此非常相似的值相除,所以我确定需要精确度为BigDecimal 。另一方面,我想保留在函数中加倍的易用性(我使用十进制SQL数据处理数组),所以计算如下:(a [i] - b [i])/ b [ i]等等,它们在其他计算中被进一步使用。我希望用户能够根据需要设计自己的公式(使用常见的数学语句)

我非常希望为String.format使用“格式”解决方案,但这会使代码不够可读(对每个变量使用String.format()...)。

非常感谢您对如何处理这些东西的建议。

+0

这可能有助于... http://stackoverflow.com/questions/8636228/bigdecimal-notation-eclipse-plugin-or-nice-external-tool – Maxx 2013-04-26 10:39:43

+0

您的要求设计打破,回去分析阶段。任何财务资料,如果没有固定的,强制性的和详尽的定义,以及如何实施舍入,那么第一个或第二个人就会认为它是错误的*。 – Durandal 2013-04-26 13:39:42

回答

0

double没有办法获得BigDecimal精度。 double s具有双精度。

如果你想保证精确的结果使用BigDecimal

可以使用long存储的整数部分创建自己的变体和int存储小数部分 - 但为什么推倒重来。

任何时间使用double s你站在双精度问题的填充。如果你在一个地方使用它们,你不妨在任何地方使用它们。

即使您仅使用它们来表示来自数据库的数据,也会将数据舍入为双精度,并且您将丢失信息。

2

什么可以做,以避免在浮动浮点错误回报。 这里没有免费的奶酪 - 使用BigDecimal。

+0

+1“免费奶酪”。 – 2013-04-26 10:32:16

+0

@Eugene,好的,谢谢你的评论,但是让我们挑战BigDecimals吧。下面的示例代码需要什么才能起作用? //我知道这是不正确的语法,但我想这样; BigDecimal a = 1234.59053232; BigDecimal b = 1.000054530; BigDecimal c; c = a/b; //或任何其他具有'人性'友好语法的公式? 并在输出得到准确的值与c给定的精度让我们说4位数? – mtx 2013-04-26 12:48:18

+0

@mtx你可以在BigDecimal上隐藏这个操作。常见的数学语句可以映射到ENUM,并提供如下操作:DIVIDE,SQUARE等。您不能在非人类BigDecimal类型上使用人类语法。在你的例子中,除法操作看起来像这样* a.divide(b,4,RoundingMode.HALF_UP)* – Eugene 2013-04-26 13:00:22

0

如果我理解你的问题,你希望使用数据类型比本地Java更精确,而不会丢失简单的数学语法(例如/ + * - 等等)。因为你不能在Java中重载运算符,所以我认为这是不可能的。

1

有效的Java(第2版):

项目48:如果确切的答案需要

  • float和double不能提供准确的结果,避免float和double和不要在需要确切结果的地方使用。 float和double类型特别不适合货币分类,因为不可能将0.1(或10的任何其他负数)表示为float或double。

  • 解决此问题的正确方法是对BigDecimal,int或long进行货币计算。

...

另一种方法是使用int或长,并跟踪小数点自己。