100 votes

Valeur de i pour (i == -i && i != 0) retourner vrai en Java

J'ai les éléments suivants if condition.

if (i == -i && i != 0)

Quelle valeur de i retournera true pour cette condition en Java ?

Je suis incapable de penser à une telle valeur de i en considérant complément à deux en Java.

J'aimerais aussi avoir une preuve algébrique de la réponse à cette condition (dans le contexte de Java) ?

125voto

dystroy Points 145126

Le seul int La valeur pour laquelle il fonctionne est Integer.MIN_VALUE .

C'est parce que les entiers sont niés à l'aide de la fonction la voie du complément à deux .

Utilisation de

System.out.println(Integer.toBinaryString(Integer.MIN_VALUE));

vous voyez que Integer.MIN_VALUE est

10000000000000000000000000000000

La prise d'une valeur négative se fait en échangeant d'abord 0 y 1 ce qui donne

01111111111111111111111111111111

et en ajoutant 1 ce qui donne

10000000000000000000000000000000

Comme vous pouvez le voir dans le lien que j'ai donné, Wikipedia mentionne le problème avec les nombres les plus négatifs et précise que c'est la seule exception :

Le nombre le plus négatif en complément à deux est parfois appelé "le nombre bizarre". nombre bizarre", car il est la seule exception.

Bien sûr, vous avez le même phénomène pour Long.Min_Value si vous le stockez dans un long variable.

Notez que cela est uniquement dû aux choix qui ont été faits concernant le stockage binaire des ints en Java. . Une autre (mauvaise) solution aurait pu, par exemple, être de nier en changeant simplement le bit le plus significatif et en laissant les autres bits inchangés, ce qui aurait évité ce problème avec MIN_VALUE mais aurait fait 2 différents 0 et une arithmétique binaire compliquée (comment auriez-vous incrémenté par exemple ?).

25voto

Stephen C Points 255558

La valeur que vous recherchez est Integer.MIN_VALUE .


J'aimerais aussi avoir une preuve algébrique de la réponse à cette condition (dans le contexte de java) ?

C'est hors sujet pour Stack Exchange. Mais vous pourriez le faire en partant de la définition des entiers de Java ( JLS 4.2 )

" Les types intégraux sont byte, short, int et long, dont les valeurs sont des entiers à deux compléments signés de 8 bits, 16 bits, 32 bits et 64 bits... ".

et

" Les valeurs des types intégraux sont des entiers dans les plages suivantes .... Pour int, de -2147483648 à 2147483647, inclus"

et la définition de l'opérateur unaire "-" de Java ( JLS 15.15.4 ) :

" Pour les valeurs entières, la négation est identique à la soustraction de zéro. Le langage de programmation Java utilise la représentation à complément à deux pour les entiers, et la plage des valeurs à complément à deux n'est pas symétrique, de sorte que la négation de l'entier ou du long négatif maximal donne le même nombre négatif maximal. Un dépassement de capacité se produit dans ce cas, mais aucune exception n'est levée. Pour toutes les valeurs entières x, -x est égal à (~x)+1."

18voto

Peter Lawrey Points 229686

En plus des réponses données jusqu'à présent...

Il y a quatre valeurs au total

int i = Integer.MIN_VALUE;
long i = Long.MIN_VALUE;
Integer i = Integer.valueOf(Integer.MIN_VALUE);
Long i = Long.valueOf(Long.MIN_VALUE);

Les valeurs enveloppées sont déballées afin qu'elles soient également vraies pour cette expression.

Remarque : les documents Math.abs.

public static int abs(int a)

Retourne la valeur absolue d'un int valeur. Si l'argument n'est pas négatif, l'argument est retourné. Si l'argument est négatif, la négation de l'argument est retournée.

Notez que si l'argument est égal à la valeur de Integer.MIN_VALUE, la valeur int représentative la plus négative, le résultat est cette même valeur, qui est négative.

et

public static long abs(long a)

Renvoie la valeur absolue d'une valeur longue. Si l'argument n'est pas négatif, l'argument est retourné. Si l'argument est négatif, la négation de l'argument est retournée.

Remarquez que si l'argument est égal à la valeur de Long.MIN_VALUE, la valeur longue représentable la plus négative, le résultat est cette même valeur, qui est négative.

Il est surprenant que Math.abs puisse retourner un nombre négatif. Cela se produit soit parce que a) il n'y a pas de valeurs positives pour -MIN_VALUE dans ces cas-là b) l'exécution de la fonction - le calcul aboutit à un dépassement de capacité.

Ce qui est également intéressant est de savoir pourquoi Byte.MIN_VALUE, Short.MIN_VALUE ne font pas cela. C'est parce que les - change le type en int pour ces derniers et donc pas de débordement.

Character.MIN_VALUE n'a pas de problème car il est égal à 0.

Float.MIN_VALUE et Double.MIN_VALUE ont une signification différente. Il s'agit de la plus petite valeur représentable supérieure à zéro. Elles ont donc des valeurs négatives valides qui ne sont pas elles-mêmes.

14voto

Mark M Points 1097

Comme les autres l'ont mentionné, cela n'est possible que si Integer.MIN_VALUE . Pour ce qui est de la preuve, permettez-moi de proposer une explication plus facile à comprendre, autrement qu'en binaire (bien qu'elle y soit toujours ancrée).

Notez que Integer.MIN_VALUE est égal à -2^31 o -2147483648 y Integer.MAX_VALUE est égal à 2^31-1 o 2147483647 . -Integer.MIN_VALUE est 2^31 qui est maintenant trop grande pour un nombre entier (puisqu'elle a dépassé le nombre d'heures de travail). MAX_VALUE ), ce qui provoque un dépassement du nombre entier, ce qui fait que Integer.MIN_VALUE encore. C'est le seul Integer qui fait cela depuis que MIN_VALUE est le seul nombre qui n'a pas d'équivalent négatif en dehors de 0.

6voto

Yves Daoust Points 6396

Tentative de preuve algébrique, utilisant modulo 2^32 arithmétique :

i == -i peut être réécrit comme suit 2 * i == 0 (ajoutant i des deux côtés), ou i << 1 == 0 .

Cette équation a deux solutions de la forme i == 0 >> 1 à savoir 0b y 10000000000000000000000000000000b obtenu par un décalage dans l'un ou l'autre des 0 o 1 à gauche.

La solution i == 0 étant exclus, il reste la solution i == 100000000000000000000000000000000b .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X