在Java中使用哪种舍入模式进行货币操作?

Ahs*_*bid 44 java bigdecimal

我已阅读java网站上BigDecimal用于货币. http://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html

但是我们应该使用哪种舍入模式?这是最合适的,也是我们最广泛的

Aar*_*lla 49

没有"正确"模式,这取决于商业案例.例子:

  • 在计算年度税时,分数通常被截断(RoundingMode.FLOOR).
  • 计算奖金时,您可能希望始终支持客户(RoundingMode.CEILING).
  • 对于账单上的税,你通常是圆的 HALF_UP
  • 在进行复杂的金融模拟时,您根本不想进行舍入.

RoundingMode文档包含很多不同模式如何工作的例子.

要获得更好的答案,您必须告诉我们您想要达到的目标.

也就是说,它BigDecimal是在Java中使用的正确类型,因为它可以保留任何精度,并且它允许您选择最适合您的情况的舍入模式.


Tom*_*icz 18

大部分时间BigDecimal是货币唯一有效的选择.但是舍入策略的选择并不那么明显.

默认为HALF_EVEN,这恰好是一个不错的选择.这种算法被称为银行家的舍入(见这里的讨论).

另一种常见的策略是HALF_UP,它更直观但统计特性略差.

还要注意,在很多时候(特别是在银行和保险业),舍入策略将由业务需求决定,对于各种用例通常是不同的.


Amo*_*ter 11

通常你会使用"half up"舍入,如下所示:

myBigDecimal.setScale(2, RoundingMode.HALF_UP);
Run Code Online (Sandbox Code Playgroud)

通过这种方式,您将舍入到小数点后两位(大多数货币都使用,例如美元和美分,显然也有例外),并且您将围绕这样的值,即半分或更多将围绕而不到半分将向下舍入.有关更多详细信息,请参阅javadoc.


Sqe*_*zer 6

对于金融应用程序 ROUND_HALF_EVEN 是最常见的舍入模式。这种模式避免了偏见。但是对于显示,您应该使用 NumberFormat 类。本课程将处理不同货币金额的本地化问题。但 NumberFormat 只接受原语。因此,如果您可以接受转换为双精度的微小精度变化,请使用最后一个。


Bre*_*ker -10

您永远不应该对货币使用小数类型。使用整数类型。这可以保持准确性,避免与浮点数相关的舍入误差

当显示金额时,然后除以适当的因子以获得非整数部分。

  • 实际上,如果使用正确,BigDecimals 是完全安全和准确的。只是不要使用“double”或“float”。 (8认同)
  • 这次讨论中信息量最大的部分是在被否决了 5 次的答案下面,这是否具有讽刺意味? (8认同)
  • @Peter:这显然是一个Java问题,而不是C/C++,在Java中,BigDecimal是专门为避免双精度和浮点数的不准确而创建的类。恐怕阿桑已经正确地弄清楚了这一点,并告诉他不要使用十进制类型并不能回答他的问题。使用双打的银行应该被起诉;-) (3认同)
  • @Peter:我工作过的两家金融机构都没有使用 C 进行敏感计算(一家使用 Java,一家使用 Smalltalk)。即使那些确实使用 C 的人,我也确信,当涉及到将比率指定为小数点后 8 位并乘以数百万美元的计算时,他们确保不只使用双精度数,并希望没有人注意到舍入错误(这在那个级别上非常重要)... (2认同)
  • @Peter,恶性通货膨胀只是一个例子,人们会看到结果溢出。计算几家大公司、中央银行和贷款机构账户的营业额和余额将是使用基元会导致溢出的另一个地方。 (2认同)