+0 и -0 показывает различное поведение для INT и поплавка данных

Joker:

Я прочитал этот пост отрицательный и положительный нуль .

В моем понимании следующего кода должны дать trueи trueкак выход.

Тем не менее, он дает falseи trueкак выход.

Я сравнение отрицательного нуля с положительным нулем.

public class Test {
     public static void main(String[] args) {
            float f = 0;
            float f2 = -f;
            Float F = new Float(f);
            Float F1 = new Float(f2);
            System.out.println(F1.equals(F));

            int i = 0;
            int i2 = -i;
            Integer I = new Integer(i);
            Integer I1 = new Integer(i2);
            System.out.println(I1.equals(I));
      }
  }

Почему мы имеем различное поведение для 0 - х для Integerи Float?

yshavit :

Ints и поплавки довольно разные звери в Java. Ints кодируются как дополнения до двух , который имеет одну значение 0. Поплавки используют IEEE 754 (на 32-битный вариант для поплавков, а также 64-бит для двойников). IEEE 754 является довольно сложным, но для целей этого ответа, вам просто нужно знать , что она состоит из трех разделов, первый из которых является знаковым. Это означает , что для любого поплавка, есть положительные и отрицательные variant¹. Это включает в себя 0, так что поплавки на самом деле есть два «нулевых» значений, +0 и -0.

Как и в сторону, два в дополнение , что Интс использовать не единственный способ закодировать целые числа в информатике. Существуют и другие методы, такие как обратный код , но у них есть причуды - как имеющие как +0 и -0 , как различные значения. ;-)

При сравнении с плавающей точкой (примитивы и двойники), Java трактует +0 и -0 как равные. Но когда вы боксировать их, Java обрабатывает их по отдельности, как описано в Float#equals. Это позволяет равно метод соответствовать их hashCodeреализациям (а также compareTo), который просто использует биты поплавка ( в том числе, подписавших значений) и пихают них , как есть в междунар.

Они могли бы выбрать какой - то другой вариант для РАВНО / хэш - код / CompareTo, но они этого не сделали. Я не уверен , что конструктивные соображения были. Но , по крайней мере , одном отношении, Float#equalsвсегда будет отличаться от поплавка примитива ==: В примитивов NaN != NaN, но для всех объектов, o.equals(o)также должны быть правдой . Это означает , что если у вас Float f = Float.NaN, то f.equals(f)несмотря на то f.floatValue() != f.floatValue().


¹ NaN (не-число) значения имеют знаковый бит, но это не имеет никакого значения, кроме для заказа, и Java игнорирует его (даже при заказе).

рекомендация

отhttp://10.200.1.11:23101/article/api/json?id=429178&siteId=1