比较Java中的两个双值



这是一个Java代码,应该测试小数点后的前三位数字是否相同。我需要在没有主方法的情况下编写这个程序。

public class areEqualByThreeDecimalPlaces {
public static boolean areEqualByThreeDecimalPlaces(double d_1, double d_2) {
double value_1 = Math.round(1000*d_1);
double value_2 = Math.round(1000*d_2);
if (value_1 == value_2) {
return true;
} else return false;
}
}

输入:

(-3.1756, -3.175)

预期输出:

true

接收的输出:

false

通过使用Math.round,它将-3.1756的值四舍五入到-3.176。但我想检查一下小数点后的三位数字是否相似。

如何更正我的代码?

关闭此代码,两个值将不相等。value_1=-3176.0value_2=-317.50

如果你想了解更多关于截断双打的知识,可以看看这个。在Java中,如何将双精度截断为小数点后两位?

检查小数点后前三位是否相同的代码应截断整数部分,通过减去初始整数部分仅保留小数部分中的数字

此外,可能需要使用Math.absMath.sign来比较从正输入和负输入检索到的值:
areEqualByThreeDecimalPlaces(3.1751, -3.1758) == true

最后一件事:为了避免在乘以1000时大输入的整数溢出,最好使用long

因此,示例实现可能如下所示:

public static boolean areEqualByThreeDecimalPlaces(double d1, double d2) {
long value1 = Math.abs((long) (d1 * 1000L) - (long) d1 * 1000L); 
long value2 = Math.abs((long) (d2 * 1000L) - (long) d2 * 1000L);
System.out.print(value1 + " == " + value2 + " ? ");
return value1 == value2;
}

或使用λ进行DoubleToLongFunction:

public static boolean areEqualByThreeDecimalPlaces(double d1, double d2) {
DoubleToLongFunction f = (d) -> Math.abs((long) (d * 1000L) - (long) d * 1000L);
return f.applyAsLong(d1) == f.applyAsLong(d2);
}

测试:

System.out.println(areEqualByThreeDecimalPlaces(-3.175, -3.1752));
System.out.println(areEqualByThreeDecimalPlaces(3.175, 3.1752));
System.out.println(areEqualByThreeDecimalPlaces(3.1751, -3.1758));
System.out.println(areEqualByThreeDecimalPlaces(5_123_456_789.123987, -90_123_456_789.123456));

输出:

175 == 175 ? true
175 == 175 ? true
175 == 175 ? true
123 == 123 ? true

您可以使用ceil而不是round

double value_1 = Math.ceil(d_1 * 1000);
double value_2 = Math.ceil(d_2 * 1000);

编辑

多亏了Alex Rudenko的评论,我意识到正确的解决方案是对负数使用ceil,对正数使用floor

double value_1 = d_1 < 0 ? Math.ceil(d_1 * 1000) : Math.floor(d_1 * 1000);
double value_2 = d_2 < 0 ? Math.ceil(d_2 * 1000) : Math.floor(d_2 * 1000);

Fabio

最新更新