Java 为什么0.4和0.40与BigDecimal不同?

Java 为什么0.4和0.40与BigDecimal不同?,java,junit,Java,Junit,我已经读到,在Java中表示货币时,BigDecimal是一种方法 但我不明白为什么我的一个单元测试失败了,并显示以下消息: org.opentest4j.AssertionFailedError: Expected :0.40 Actual :0.4 “实际”值是BigDecimal.valueOf(0.398).setScale(2,舍入模式。向上舍入)的结果 所以我想我的问题有两个部分: 为什么这些价值观不被平等对待 如何将$0.40表示为一个BigDecimal,而不触发

我已经读到,在Java中表示货币时,BigDecimal是一种方法

但我不明白为什么我的一个单元测试失败了,并显示以下消息:

org.opentest4j.AssertionFailedError:   
Expected :0.40  
Actual   :0.4
“实际”值是
BigDecimal.valueOf(0.398).setScale(2,舍入模式。向上舍入)
的结果

所以我想我的问题有两个部分:

  • 为什么这些价值观不被平等对待
  • 如何将$0.40表示为一个BigDecimal,而不触发这种不匹配

  • 大小数是数字和“刻度”的组合。2 BD不认为自己是平等的,除非两者都相等。我建议使用
    .compareTo(other)==0)
    来获得答案

    注:我不认为使用BD是处理货币问题的好方法

    通常有两种方法来接近货币。简单的方法和困难的方法

    简单的方法是将美分存储在
    int
    long
    中。因此,将$0.40简单地存储为
    40
    ,类似$12.50的东西将存储为
    1250
    。你现在有两个问题:你不能代表半美分,可能会发生溢出(你不能代表高于2^31-1美分的金额,但那是…很多美分。让它成为一个
    长的
    ,我们远远超过了整个世界的GDP)

    但是,一般来说,半美分是个问题。以这个问题为例:

    我有4美分。我想把这些分给3个人

    那么,我们该怎么办?BigDecimal在这里帮不了你;你不能完美地用BD表示4除以3。你必须在某个地方取整(它是1.33333333…BD不能表示无限序列)。即使它可以或者你决定以惊人的数量(比如说200位数字)取整,现在呢?你不能告诉你的银行转帐三分之一美分。没有简单的答案:如果这是你的应用程序需要做的,那么你需要决定如何处理。例如,“剩下的一分钱是给房子的”或“软件随机挑选一个接收者;他们得到2美分,另外2人得到1美分)


    换句话说,如果“只使用int/long”不起作用,那么BigDecimal也不好。

    根据javadocs,将这个BigDecimal与指定的对象进行比较,以确保相等。与compareTo不同,此方法仅当两个BigDecimal对象的值和比例相等时才认为它们相等(因此,使用此方法进行比较时,2.0不等于2.00)。
    0.40
    表示您已测量到第一百位,并且您肯定知道第一百位是
    0
    0.4
    表示您尚未测量到第一百位,并且不知道第一百位的值是多少。也可以尝试使用
    compareTo
    No,您应该使用
    assertEquals(0,actualBigDecimal.compareTo(expectedBigDecimal))3个人分4美分根本没有答案
    BigDecimal
    的行为与这里的银行完全一样。我想使用
    long
    可能会迫使开发人员面对四分问题,比如四分问题,使用
    BigDecimal
    可以让他们在不考虑后果的情况下愉快地分开。措辞恰当的回答。@user207421确实如此,这正是我的观点:使用BD并不是解决所有问题的灵丹妙药。使用BD比使用长的表示美分要复杂得多,我试图告诉OP,这种额外的复杂性通常是不值得的。