我有以下代码:计算两个双打的其余部分的Java
Double x = 17.0;
Double y = 0.1;
double remainder = x.doubleValue() % y.doubleValue();
当我运行此我得到的余数= 0.09999999999999906
任何想法,为什么?
我基本上需要检查x是否完全被y整除。你能否建议用java做替代方法?
谢谢
我有以下代码:计算两个双打的其余部分的Java
Double x = 17.0;
Double y = 0.1;
double remainder = x.doubleValue() % y.doubleValue();
当我运行此我得到的余数= 0.09999999999999906
任何想法,为什么?
我基本上需要检查x是否完全被y整除。你能否建议用java做替代方法?
谢谢
由于如何表示浮点数。
如果你想要的精确值,使用BigDecimal
:
BigDecimal remainder = BigDecimal.valueOf(x).remainder(BigDecimal.valueOf(y));
另一种方式来那就是多了10(或100,1000),转换为int
每个值,然后使用%
。
您需要比较允许舍入误差的结果。
if (remainder < ERROR || remainder > 0.1 - ERROR)
而且,当你想使用double
这是正确的当你的数据确实来自浮点/双精度源(并且不仅仅是离散数据伪装成浮点值)时使用的答案,并且你想知道“x”是否“非常接近”y的精确倍数'。 – 2015-06-19 21:48:31
This后应该帮助你不使用双。它解释了为什么你看到这种行为,并且还讨论了BigDecimal类。
您至少应该引用该链接中与OP最重要的部分。否则,这听起来像你没有给予太多的关注。 – 2016-01-28 03:43:07
在计算机上期望双算术的精确结果是有问题的。基本的罪魁祸首是我们人类大多使用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);
}
只是一个补充:你可以使用'BigDecimal.ZERO'而不是'valueOf(0.0)'来提高可读性。如果可能的话,最好使用'new BigDecimal(String)'构造函数,因为'valueOf(double)'仍然存在精度/舍入错误。 – 2011-04-05 13:48:31
浮点运算仅是实数运算的近似值:http://en.wikipedia.org/wiki/Floating_point#Accuracy_problems – LumpN 2011-04-05 13:13:36