2010-05-29 8 views
5

Может ли кто-нибудь мне угодить, почему выход следующей программы не «отличается от другого»?Номера с плавающей запятой в Java

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"); 
} 

о/р: разные же

+0

Почему это должно быть? –

ответ

11

6.5 имеет конечное двоичное представление: 110.1

Любой плавающий тип с по крайней мере 4 значимых битов может представлять это число отлично.

+110,100000000000000000000 (поплавок)
= 6,5

110,10000000000000000000000000000000000000000000000000 (двойной)
= 6,5

3,2 с другой стороны, имеет бесконечное двоичное представление: 101.0011001100110011 ...

поплавок и двойной не имеют бесконечной точности и, следовательно, могут только приблизиться к этому числу: (

101,001100110011001100110 (поплавок)
= 3,2000000476837158203125

101,00110011001100110011001100110011001100110011001101 (двойной)
= 3,20000000000000017763568394002504646778106689453125

Как вы можете ясно видеть, эти цифры не совпадают!

+0

+1 к вам, потому что это единственный ответ, который на самом деле отвечает на заданный вопрос. Я не знаю, почему OP принял другой ответ, который определенно не объясняет, почему один тест дает * «тот же» *, а другой * «другой» *. – NoozNooz42

+2

Я бы просто добавил, что другая причина этого в том, что Java продвигает менее точные типы для более точных типов для сравнения, что делает возможным сравнение 3.2 и 3.2f. Если бы он усекал более длинный тип, они были бы одинаковыми, но, к счастью, он (например, C) использует * расширение примитивных преобразований *, чтобы делать то, что ожидало большинство людей: http://bit.ly/d8Yx3N – tgamblin

+0

@ NoozNooz42: Эй , Я получил это правильно также: ( –

3

Поскольку 3.2f является значением float и 3.2 это значение double. Числа с плавающей запятой всегда немного неточны, потому что двоичное представление не может точно их реализовать, поэтому сравнение их для точного равенства - плохая идея. В частности, Сравнение поплавков с удвоениями. Выражения, такие как 3.2f == 3.2f, обычно в порядке, но даже те, которые могут терпеть неудачу на некоторых языках, например. если они представляют цифры в регистре более точно, чем в памяти.

+0

+1 потому что это объяснение гораздо более тщательное, чем я хотел написать. :) – edl

+0

Я думаю, что вопрос в том, почему один из них сравнивается как равный. ОП ожидает, что они оба будут неравными. –

+3

«Числа с плавающей запятой * всегда * слегка неточны» -> неправильно. float и double могут представлять дроби с конечными двоичными представлениями, например 6.5. См. Мой ответ для деталей. – fredoverflow

0

«3.2f» - это тип поплавка. «3.2» имеет тип double.

0

Кроме того, я думаю, что все с десятичным значением по умолчанию в двойное, поэтому, когда вы делаете сравнение, вы должны добавить 'f', а также if(f2==6.4f).

5

Поскольку 3.2 не представляется точно так же, как число с плавающей запятой, а 6.5 (подсказка: 6.5 = 13 * 2^(- 1)), а также тот факт, что 3.2 является литералом double, но 3.2f является литералом float ,

Смежные вопросы