2010-02-13 8 views
10

diesen Code vor:Warum ist der resultierende Typ einer Division von kurzen Ganzzahlen in Java keine kurze Ganzzahl?

public class ShortDivision { 
    public static void main(String[] args) { 
     short i = 2; 
     short j = 1; 
     short k = i/j; 
    } 
} 

Kompilieren der Fehler dadurch erzeugt

ShortDivision.java:5: possible loss of precision 
found : int 
required: short 
     short k = i/j; 

weil die Art des Ausdrucks i/j ist offenbar int und daher muss kurz gegossen werden.

Warum ist der Typ i/j nicht kurz?

+1

Die Umwandlung eines int in einen kurzen Wert würde möglicherweise zu einem Verlust der Genauigkeit führen. (-32768/-1) –

Antwort

16

Vom Java spec:

5.6.2 Binary Numerische Promotion

Wenn ein Operator mit einem Paar von Operanden binäre Zahlen Aktion gilt, von denen jeder einen Wert eines numerischen Typs bezeichnen muss, die Folgende Regeln gelten, um die Operanden nach Bedarf zu konvertieren:

Wenn einer der Operanden vom Typ double ist, wird der andere in double konvertiert.

Andernfalls, wenn einer der Operanden vom Typ float ist, wird der andere in float konvertiert.

Andernfalls, wenn einer der Operanden vom Typ long ist, wird der andere in long konvertiert.

Andernfalls werden beide Operanden in den Typ int konvertiert.

Für binäre Operationen werden kleine Integer-Typen zu int und das Ergebnis der Operation ist int gefördert.


EDIT: Warum ist es so? Die kurze Antwort ist, dass Java dieses Verhalten von C kopiert hat. Eine längere Antwort könnte mit der Tatsache zu tun haben, dass alle modernen Maschinen mindestens native 32-Bit-Berechnungen durchführen, und es könnte für manche Maschinen tatsächlich schwieriger sein, 8-Bit und 16-Bit-Operationen

Siehe auch: OR-ing bytes in C# gives int

+0

weiter: Binäre numerische Hochstufung wird an den Operanden bestimmter Operatoren durchgeführt: - Die multiplikativen Operatoren *,/und% – akf

+0

OK, ich verstehe, dass die Sprachspezifikation besagt, dass die Sprache sich so verhalten soll (Andernfalls würde der Compiler den Fehler an erster Stelle nicht erzeugen). Aber ich verstehe die Motivation dahinter nicht. Warum fördern sie die Typen vor der Teilung, anstatt nur die Shorts zu teilen? – flodin

+0

Meine Wette ist auf "so ist es in C". Java wurde entwickelt, um für C++ - Programmierer attraktiv zu sein - das erfordert, dass die Dinge gleich sind –

2

Im Hinblick auf die Motivation: Es kann zu diesem Verhalten die Alternativen vorstellen und sehen, warum sie nicht funktionieren:

Alternative 1: das Ergebnis sollte immer die gleiche wie die Eingänge sein .

Was sollte das Ergebnis für das Hinzufügen eines int und eines short sein?

Was sollte das Ergebnis sein, um zwei Kurzschlüsse zu multiplizieren? Das Ergebnis wird im Allgemeinen in ein int passen, aber da wir zu kurz abschneiden, werden die meisten Multiplikationen stillschweigend fehlschlagen. Casting zu einem int danach wird nicht helfen.

Alternative 2: Das Ergebnis sollte immer der kleinste Typ sein, der alle möglichen Ausgaben darstellen kann.

Wenn der Rückgabetyp eine kurze war, wäre die Antwort nicht immer als kurz darstellbar.

Ein Short kann die Werte -32.768 bis 32.767 enthalten. Dann wird dieses Ergebnis einen Überlauf verursachen:

short result = -32768/-1; // 32768: not a short 

So wird Ihre Frage: Warum fügt das Hinzufügen von zwei Ints nicht lange zurück? Was sollte Multiplikation von zwei Ints sein? Eine lange? Eine BigNumber, um den Fall der Quadrierung des ganzzahligen Minwerts zu behandeln?

Alternative 3: Wählen Sie das, was die meisten Menschen wahrscheinlich die meiste Zeit wollen

So sollte das Ergebnis sein:

  • int für zwei Shorts Multiplikation oder eine beliebige Operationen int.
  • kurz, wenn das Hinzufügen oder Subtrahieren von Shorts, eine kurze durch eine Integer-Typ Dividieren, Multiplizieren zwei Bytes, ...
  • Byte, wenn ein Byte nach rechts bitshifting, int nach links, wenn bitshifting.
  • etc ...

Erinnerung an alle besonderen Fällen schwierig wäre, wenn es ihnen keine grundlegende Logik. Es ist einfacher zu sagen: Das Ergebnis von Integer-Operationen ist immer ein int.

+0

Was die Leute wollen, ist nicht immer das Gleiche wie das, was eine gute Idee ist, wenn man es neu gestaltet. Ein gutes Beispiel ist die QWERTY-Tastaturanordnung. Ursprünglich entworfen, um Schreibkräfte * zu verlangsamen, damit Schreibmaschinen sich nicht stauen würden. Trotzdem kann ich mir nicht vorstellen, etwas anderes zu verwenden, als ich es gewohnt bin. –

+0

@Peter Lawrey: Ja. Wenn Henry Ford die Leute gefragt hätte, welche Art von Auto er herstellen sollte, hätten viele nach einem Wagen mit ** 6 ** Pferden anstatt 4 gefragt. Zu hören, was Ihre Benutzer wollen, ist eine gute Sache, aber manchmal müssen Sie geben Sie unterscheiden sich von dem, was sie wollen, weil sie sich nicht einmal eine andere Lösung vorstellen können als das, was sie gewohnt sind. –

+0

Für Sprachen ohne Bedienerüberlastung, warum sollte das Ergebnis nicht das kleinere von (größtes mögliches Ergebnis) oder (Größe des empfangenden Containers) sein? In den meisten Fällen würde eine solche Regel einen Code ergeben, der so klein oder kleiner als alles ist, was ausgedrückt werden könnte, was arithmetisch korrekte Ergebnisse ergeben würde, wenn Ansatz 1 verwendet würde. Zum Beispiel, wenn Variablen 32 Bits sind, würde 'p = (x * y)/z;' eine 32x32-> 64 Multiplikation und eine 64/32-> 32 Division machen. Wenn "p" und "z" 16 Bits wären, würde dies eine 32 × 32 → 64 Multiplikation, eine 64 → 32 Überlauf-kontrollierte Reduktion und eine 32/16 → 16 Teilung sein. – supercat

0

Es ist nur eine Design-Option, die mit C/C++ konsistent ist, die dominierende Sprachen waren, als Java entwickelt wurde.

Zum Beispiel könnte i * j implementiert werden, so dass der Typ von Byte => kurz, kurz => int und int => lang, und dies würde Überläufe vermeiden, aber es nicht. (Es ist in einigen Sprachen möglich) Casting könnte verwendet werden, wenn das aktuelle Verhalten gewünscht wurde, aber der Verlust einiger Bits wäre klar.

Ähnlich könnte i/j von Byte/short => float oder int/long => double aufgefordert werden.

Verwandte Themen