2009-07-03 4 views
1

Hmmm. Betrachten Sie dieses Programm, dessen Ziel es ist, den besten Weg zu finden, die unteren 16 Bits einer ganzen Zahl als eine ganze Zahl mit Vorzeichen zu erhalten.Erhalten der unteren 16 Bits eines Java-Int als vorzeichenbehafteter 16-Bit-Wert

public class SignExtend16 { 
    public static int get16Bits(int x) 
    { 
     return (x & 0xffff) - ((x & 0x8000) << 1); 
    } 

    public static int get16Bits0(int x) 
    { 
     return (int)(short)(x); 
    }  

    public static void main(String[] args) 
    { 
     for (String s : args) 
     { 
      int x = Integer.parseInt(s); 
      System.out.printf("%08x => %08x, %08x\n", 
       x, get16Bits0(x), get16Bits(x)); 
     } 
    } 
} 

Ich wollte den Code in get16Bits0 verwenden, aber ich habe die Warnung „Unnötige Besetzung von kurz bis int“ mit Eclipse-Compiler und es macht mich stutzig, den Compiler zu denken konnte mein „unnötiges cast“ optimiert out . Wenn ich es auf meinem Rechner mit dem Compiler von Eclipse ausführe, bekomme ich identische Ergebnisse von beiden Funktionen, die sich so verhalten, wie ich es vorhabe (Testargumente: 1 1111 11111 33333 66666 99999). Bedeutet das, dass ich get16Bits0 benutzen kann? (Mit passenden Warnungen an zukünftige Code-Betreuer) Ich habe immer angenommen, dass JRE und das Compiler-Verhalten beide maschinenunabhängig für die Arithmetik sind, aber dieser Fall testet meinen Glauben etwas.

Antwort

5

Da numerische Umwandlungen implizit-freundlich sind, denke ich, dass der einzige Grund, warum Sie die Warnung erhalten, ist, dass der Compiler bei der Rückkehr immer die Umwandlung in int durchführt, was Ihre explizite Umwandlung überflüssig macht.

+0

ooh! Vielen Dank! Noch besser. –

0

ja, get16Bits0 sollte funktionieren, fügen Sie einfach einen suppressWarning Metatag vor der Funktion hinzu.

5

Nun, zunächst einmal ist die Warnung korrekt, da Sie sich immer mit arithmetischen Umrechnungen "nach oben" bewegen können. Nur die andere Möglichkeit benötigt eine Umwandlung, da Sie möglicherweise Daten verlieren (oder die Genauigkeit für Gleitkommazahlen).

Wenn Sie von "int" auf "short" reduzieren, müssen Sie angeben, dass es beabsichtigt ist, indem Sie einen Cast verwenden. Aber wenn Sie den kurzen Wert zurück in int konvertieren, besteht keine Gefahr und dies geschieht automatisch.

Also, alles, was Sie brauchen, ist

return (short) x; 
4

Wenn Sie die Besetzung vermeiden wollte, können Sie es als tun könnte:

(x << 16) >> 16 

Diese Technik funktioniert auch mit einer unterschiedlichen Anzahl von Bits. Sprich Boden 15:

(x < < 17) >> 17

ändern >> für nicht signierte Version >>>.

Verwandte Themen