Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Поплавок и двойная путаница

Автор вопроса: Imtiaz Zaman NishithОтветов: 5

Я смущен поведением числа с плавающей запятой, увидев результат следующего фрагмента кода.

    float var1 = 5.4f;
    float var2 = 5.5f;

    if(var1 == 5.4)
        System.out.println("Matched");
    else
        System.out.println("Oops!!");

    if(var2 == 5.5)
        System.out.println("Matched");
    else
        System.out.println("Oops!!");

Вывод:

Oops!!
Matched

Это из-за того, что десятичное число не может быть точно представлено в двоичном формате с основанием 2? ИЛИ Это из-за точности, поскольку я сравниваю переменную типа float с типом double? Если да, то почему он отлично работает для следующей переменной?

  • Информации много, просто погуглите :) Во-первых, используйте double over float, а также посмотрите _1 _... vikingsteve 19.09.2013
  • возможный дубликат Сравнение примитивов float и double в Java devnull 19.09.2013
  • В другом вопросе это очень хорошо обсуждается stackoverflow.com/questions/1088216/ AurA 19.09.2013

javatype-conversion

Ответы

Ответ 1 · рейтинг 16 · Jon Skeet

Это из-за того, что десятичное число не может быть точно представлено в двоичном формате с основанием 2?

да. По сути, 5.4f и 5.4d не одинаковы, потому что ни один из них не является точным представлением 5.4.

5.5f и 5.5d одинаковы, потому что они оба являются точным представлением 5.5.

Обратите внимание, что 5.4 неявно совпадает с 5.4d - типом по умолчанию для литерала с плавающей запятой является double. Любое использование бинарного оператора с операндами float и double повысит float до double и выполнит операцию с двумя значениями double.

Это может упростить представление об этом в терминах десятичных типов. Предположим, у нас есть два типа, Decimal5 и Decimal10, которые представляют собой десятичные числа с 5 или 10 значащими цифрами. Затем рассмотрим "треть" и "четверть":

A third:
Decimal5:  0.33333
Decimal10: 0.3333333333

A quarter (showing trailing zeroes just for clarity):
Decimal5:  0.25000
Decimal10: 0.2500000000

При сравнении значения Decimal5, ближайшего к третьему, со значением Decimal10, значение Decimal5 будет преобразовано в значение Decimal10, равное 0,3333300000, что не равно 0,3333333333. Это похоже на ваш первый пример.

Однако при сравнении значений для квартала значение Decimal5 0,25000 преобразуется в 0,2500000000, что совпадает со значением Decimal10, которое мы имеем для квартала. Это похоже на ваш второй пример.

Конечно, двоичные типы с плавающей запятой немного сложнее, чем это, с нормализацией, субнормальными числами и т.д., но для целей вашего примера эта аналогия достаточно близка.

Ответ 2 · рейтинг 6 · Prabhaker A

Разница в том, что 5.5 может быть точно представлена ​​как в float, так и в double, тогда как 5.4 не может быть представлена ​​точно.
ссылка http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html

Ответ 3 · рейтинг 3 · anubhava

Замените условие if на:

if(var1 == 5.4f)
    System.out.println("Matched");
else
    System.out.println("Oops!!");

if(var2 == 5.5f)
    System.out.println("Matched");
else
    System.out.println("Oops!!");

Затем он будет печатать Matched оба раза. Причина в том, что без квалификатора f в конце Java обрабатывает 5.4 как double, что не может быть представлено точно по сравнению с 5.5.

Ответ 4 · рейтинг 2 · Rafi Kamal

Легко увидеть:

if(var1 == 5.4f)
    System.out.println("Matched");
else
    System.out.println("Oops!!");

if(var2 == 5.5f)
    System.out.println("Matched");
else
    System.out.println("Oops!!");

Вывод:

Matched
Matched

Двоичное представление 5.4f и 5.4d не совсем то же самое

Ответ 5 · Darwing

Если вы хотите сравнить типы с плавающей запятой, вы должны использовать сравнение с эпсилоном. Здесь вы можете увидеть все способы, которые вы можете использовать для сравнения типов с плавающей запятой. .

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы