Кто-либо мог понравиться мне, почему вывод следующей программы не "отличающийся отличающийся"?
public static void main(String[] args)
{
float f1=3.2f;
float f2=6.5f;
if(f1==3.2)
System.out.println("same");
else
System.out.println("different");
if(f2==6.5)
System.out.println("same");
else
System.out.println("different");
}
o/p: отличающийся то же
6.5 имеет конечное двоичное представление: 110.1
Любой плавающий тип с как минимум 4 значащими битами может идеально представить это число.
110.100000000000000000000 (с плавающей запятой)
= 6,5
110,10000000000000000000000000000000000000000000000000 (двойной)
= 6.5
3.2, с другой стороны, имеет бесконечное двоичное представление: 101.0011001100110011 ...
float и double не имеют бесконечной точности и, таким образом, могут только приблизительно соответствовать этому числу: (
101.001100110011001100110 (float)
= 3.2000000476837158203125
101.00110011001100110011001100110011001100110011001101 (двойной)
= 3.20000000000000017763568394002504646778106689453125
Как видите, эти числа не совпадают!
Потому что 3.2f - это float
, а 3.2
- это double
. Числа с плавающей запятой всегда немного неточны, поскольку двоичное представление не может реализовать их точно, поэтому сравнивать их на предмет точного равенства - плохая идея. Особенно при сравнении плавающих чисел с двойными. Выражения типа 3.2f == 3.2f
обычно подходят, но даже они могут быть неудачными в некоторых языках, например, если они представляют числа в регистрах более точно, чем в памяти.
Потому что 3.2 не может быть представлено точно как число с плавающей запятой, а 6.5 может (подсказка: 6.5 = 13 * 2^(-1)), а также тот факт, что 3.2 - это double
литерал, а 3.2f - float
литерал.
Кроме того, я думаю, что все, что имеет десятичное значение, по умолчанию превращается в двойное, поэтому, когда вы проводите сравнение, вы должны добавить 'f', а также if (f2 == 6.4f )
.