public class Main {
public static void main(String[] args) {
System.out.println(areEqualByThreeDecimalPlaces(-3.1759D, -3.175D));
System.out.println(areEqualByThreeDecimalPlaces(3.174D, 3.175D));
System.out.println(areEqualByThreeDecimalPlaces(-3.0D, -3.0D));
}
public static boolean areEqualByThreeDecimalPlaces(double num1, double num2) {
float f = (float) Math.abs(num1 - num2)*1000f;
double d = Math.abs(num1 - num2)*1000d;
//double d = 1.000000d;
System.out.println(String.format("double: %f float: %f%nd: %f\t\t f: %f", Math.floor(d), Math.floor(f), d, f));
return Math.floor(f) < 1;
}}
在上面的代码中,我试图验证作为参数发送到areEqualByThreeDecimalPlaces()
的两个double值是否等于/等于3个小数位。在这种方法中,我试图理解为什么使用双精度变量Math.floor()
的{{1}}在使用d
分配计算值后不能按预期工作。我在Math.abs() * 1000d
上使用了float
类型后,似乎对f
变量float
起作用了-这让我有些困惑。为什么Math.abs()
函数不能像预期的Math.floor()
变量double
那样对d
变量float
起作用?
输出:
f
这是上面代码的输出。这里的double: 0.000000 float: 0.000000
d: 0.900000 f: 0.900000
true
double: 0.000000 float: 1.000000
d: 1.000000 f: 1.000000
false
double: 0.000000 float: 0.000000
d: 0.000000 f: 0.000000
true
Process finished with exit code 0
和double:
部分是float:
和Math.floor(d)
的输出。 Math.floor(f)
发送的第二组值是此命令main()
给出的值,从而导致意外行为。对于System.out.println(areEqualByThreeDecimalPlaces(3.174D, 3.175D));
变量double
,预期输出看起来像d
变量float
的输出,但是f
返回Math.floor(d)
,其中我希望它是0.000000
。
答案 0 :(得分:-1)
以此替换您的上一个打印声明:
System.out.println(String.format("double: %2.15f float: %f%nd: %2.15f\t\t f: %f", Math.floor(d), Math.floor(f), d, f));
这将打印出带有更多小数位的数字。然后您可以看到d
实际上小于1
。发生这种情况是因为浮点数(双精度或浮点型)通常不能精确表示十进制值。
这是由于以下事实:浮点数在内部表示为二进制值(以2为底)。因此,在十进制表示形式中,1/5正好是0.2,但是在以2为基数的表示形式中,它是一个无限的浮点数,例如1/3在十进制表示形式中是0.333...。