2010-05-09 9 views
4

Je reçois une erreur de "perte de précision" alors qu'il n'y en aurait pas, AFAIK."perte de précision possible" Java devient fou ou il me manque quelque chose?

ceci est une variable d'instance:

byte move=0; 

cela se produit dans une méthode de cette classe:

this.move=(this.move<<4)|(byte)(Guy.moven.indexOf("left")&0xF); 

mouvement est un octet, mouvement est toujours un octet, et le reste est en cours de coulée à un octet.

Je reçois cette erreur:

[javac] /Users/looris/Sviluppo/dumdedum/client/src/net/looris/android/toutry/Guy.java:245: possible loss of precision 
[javac] found : int 
[javac] required: byte 
[javac]    this.move=(this.move<<4)|(byte)(Guy.moven.indexOf("left")&0xF); 
[javac]          ^

J'ai essayé beaucoup de variations, mais je reçois toujours la même erreur.

Je suis maintenant désemparé.

+1

Que faire si le déplacement est de 128? Lorsque vous le déplacez de 4 bits, cela entraîne une perte de précision. Est-ce que "byte << N" est défini pour retourner un autre octet, ou un int? –

Répondre

8

En fait, tous les opérateurs logiques (& | ^) renvoient un int, indépendamment de leurs opérandes. Vous devez aussi lancer le résultat final de x | y.

+0

oh! Merci! (pour leonbloy et ZZ aussi) –

8

C'est parce que this.move<<4 renvoie un int. Lorsque Java trouve a shift operator, s'applique à chaque opérande; dans ce cas, les deux opérandes sont promus à int, et le résultat est le même. Le comportement est similaire pour les autres opérateurs Java; voir une discussion connexe et instructive, "Varying behavior for possible loss of precision".

+0

Le lien était très utile pour moi, mais il n'y a pas d'exemple sur le décalage au niveau du bit. L'explication il y a sur l'énoncé d'affectation composé. – CEGRD

5

Les opérandes OR au niveau du bit font l'objet d'une promotion numérique binaire. Voici comment son défini dans JLS,

5.6.2 Binary Numeric Promotion

When an operator applies binary numeric promotion to a pair of operands, each of which must denote a value of a numeric type, the following rules apply, in order, using widening conversion (§5.1.2) to convert operands as necessary:

  • If either operand is of type double, the other is converted to double.
  • Otherwise, if either operand is of type float, the other is converted to float.
  • Otherwise, if either operand is of type long, the other is
    converted to long.
  • Otherwise, both operands are converted to type int.

Comme vous pouvez le voir, il n'y a aucun type d'octet de sorte que tous les octets sont promus int par défaut. Vous devez le renvoyer à l'octet pour vous débarrasser de l'avertissement.

this.move=(byte)((this.move<<4)|(Guy.moven.indexOf("left")&0xF)); 
+0

En fait ici une paire de promotions numériques Unary ocurr, pas un binaire voir http://docs.oracle.com/javase/specs/jls/se5.0/html/expressions.html#5121 – leonbloy

Questions connexes