这是一个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.abs
或Math.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