我遇到了以下程序
class Boolean {
public static void main(String argv[]) {
boolean x;
x = 4.4f == 4.4;
System.out.println(x);
}
}
以下程序的输出为false
但是如果我们按照以下方式编写程序,那么
class Boolean {
public static void main(String argv[]) {
boolean x;
x = 4.5f == 4.5;
System.out.println(x);
}
}
在这种情况下,输出为true
有人可以解释我为什么吗?
答案 0 :(得分:3)
通常不应将浮点值与==运算符进行比较。你应该使用'足够接近'的比较,比如检查值是否有一些小值:
double epsilon = 0.000001
boolean equal = Math.abs(value1-value2) < epsilon
在你的例子中,4.4f不等于4.4,因为java将浮点值默认为 double 类型,即64位,并将它们的java转换为4.4f比较为double,这会导致它与原始的双倍值4.4略有不同(因为用二进制表示小数部分的问题)。
这是关于浮点数的好link。
答案 1 :(得分:1)
问题是像数字这样的计算机要基于基数2而不是像我们这样的基数10。
4.4是二进制的无限分数(如0.333333333 ...对于我们而言),浮点数比双精度数少,因此4.4f中的数字少于4.4中的数字,使它们不同。
4.5不是无限分数。
注意:每当你需要比较浮点数或双打数时,你应该总是检查差异的大小,而不仅仅是检查是否相等。
答案 2 :(得分:1)
运行此代码以了解如何将float转换为double适用于这些情况
NumberFormat nf = new DecimalFormat("0.00000000000000000000");
System.out.println(nf.format(4.4f));
System.out.println(nf.format(4.4));
System.out.println(nf.format(4.5f));
System.out.println(nf.format(4.5));
答案 3 :(得分:0)
这是因为当double被截断为float时会出现舍入错误。有时你得到它有时你不会。
4.4f是一个浮点数,4.4是一个双精度数。
答案 4 :(得分:0)
你的prgramm将16位浮点数与32位双精度值进行比较。 Internaly它表示为IEEE754,因此差异是舍入误差,在某些情况下由于精度不同而导致这种不等式。
答案 5 :(得分:0)
这可以归结为浮点数不是双精度,你不能轻易进行直接比较,因为浮点数只是一个近似值。看看下面的代码:
public static void main(String args[]) {
double a, b;
a = 4.4f;
b = 4.5f;
System.out.println("4.4f implicitly cast to a double = "+a);
System.out.println("4.5f implicitly cast to a double = "+b);
}
你会看到4.4f,当隐式转换为double时实际上是4.400000095367432。
答案 6 :(得分:0)
除了大家所说的,这里有一个非常流行的例子来演示浮点运算。
System.out.println(0.3 - 0.2 - 0.1);
不会打印0
。实际上,由于在二进制表示中某些分数是非终止重复的浮点运算中发生的截断错误,它会打印一个非常小的数字。