2011-04-05 53 views
4

我有以下代码:计算两个双打的其余部分的Java

Double x = 17.0; 
Double y = 0.1; 

double remainder = x.doubleValue() % y.doubleValue(); 

当我运行此我得到的余数= 0.09999999999999906

任何想法,为什么?

我基本上需要检查x是否完全被y整除。你能否建议用java做替代方法?

谢谢

+1

浮点运算仅是实数运算的近似值:http://en.wikipedia.org/wiki/Floating_point#Accuracy_problems – LumpN 2011-04-05 13:13:36

回答

10

由于如何表示浮点数。

如果你想要的精确值,使用BigDecimal

BigDecimal remainder = BigDecimal.valueOf(x).remainder(BigDecimal.valueOf(y)); 

另一种方式来那就是多了10(或100,1000),转换为int每个值,然后使用%

3

您需要比较允许舍入误差的结果。

if (remainder < ERROR || remainder > 0.1 - ERROR) 

而且,当你想使用double

+0

这是正确的当你的数据确实来自浮点/双精度源(并且不仅仅是离散数据伪装成浮点值)时使用的答案,并且你想知道“x”是否“非常接近”y的精确倍数'。 – 2015-06-19 21:48:31

1

This后应该帮助你不使用双。它解释了为什么你看到这种行为,并且还讨论了BigDecimal类。

+0

您至少应该引用该链接中与OP最重要的部分。否则,这听起来像你没有给予太多的关注。 – 2016-01-28 03:43:07

1

在计算机上期望双算术的精确结果是有问题的。基本的罪魁祸首是我们人类大多使用10号基地,而计算机通常以2号基地存储数字。两者之间存在转换问题。

该代码会做你想要什么:

public static void main(String[] args) { 
    BigDecimal x = BigDecimal.valueOf(17.0); 
    BigDecimal y = BigDecimal.valueOf(0.1); 

    BigDecimal remainder = x.remainder(y); 
    System.out.println("remainder = " + remainder); 

    final boolean divisible = remainder.equals(BigDecimal.valueOf(0.0)); 
    System.out.println("divisible = " + divisible); 

} 
+1

只是一个补充:你可以使用'BigDecimal.ZERO'而不是'valueOf(0.0)'来提高可读性。如果可能的话,最好使用'new BigDecimal(String)'构造函数,因为'valueOf(double)'仍然存在精度/舍入错误。 – 2011-04-05 13:48:31