2017-01-25 10 views
1

Ich versuche den ganzzahligen Mittelpunkt zwischen zwei ganzen Zahlen zu finden. Zum Beispiel wäre Mitte (2,3) 2, nicht 2,5. Ich hatte die unten, die gut funktioniert, aber ich würde gerne mit Zahlen von MIN_VALUE bis MAX_VALUE arbeiten, und dies verursacht Überlauf so völlig falsche Ergebnisse.Java findet den Mittelpunkt zwischen zwei Ganzzahlen

public static int mid(int x, int y){ 
    int midpoint = (x+y)/2; 
    return midpoint; 
} 

Ich habe jetzt bekam:

public static int mid(int x, int y){ 
    int low = Math.min(x, y); 
    int high = Math.max(x, y); 
    int midpoint = (low + high) >>> 1; 
    return midpoint; 
} 

Dies ist für Werte von x und y von 0 bis Integer.MAX_VALUE zu funktionieren scheint, ist jedoch falsch, wenn x eine negative Zahl ist und i‘ Ich bin mir nicht sicher, warum das so ist?

+0

Es funktioniert auch nicht, wenn 'x + y> MAX_VALUE'. – molbdnilo

+1

Do mit 'double' und dann zurück in int konvertieren? Werben Sie für die '' '' '' '' '' '' '' '' '' '' '' '' '' Ersten? – markspace

+0

Fehlerhaftes Verhalten bei negativer Ganzzahl kann nicht reproduziert werden. Das einzige, was ich überprüfen konnte, ist, dass dieser Code von Überlauf-Problemen betroffen ist. – Paul

Antwort

1

Sie können mit convert zu lange arbeiten um und zurück:

public static int mid(int x, int y) { 
    return (int) (((long)x + y)/2); 
} 
+0

Kann '(long) x + y' immer noch eine ganze Zahl überlaufen? –

+0

nein, wird es auf lange – Jerry06

+1

Wenn einen der Werte in einer Rechenoperation gegossen (+, -, *, /,%) lang ist, dann werden alle Werte auf langen Typen vor der Rechenoperation umgewandelt in ausgeführt. Also wird '(long) x + y'' long' zurückgeben, danach '((long) x + y)/2' wird' long' zurückgeben, liegt aber immer noch im 'int' Bereich, also der Cast auf' int' wird funktionieren – Jerry06

1

Was diese Suchbegriffe?

public static int mid(int x, int y){ 
    long difference = (long)y - x; 
    long adDiff = difference/2; 
    return (long) (x + adDiff); 
} 

Sie haben es zu einem langen zu werfen, so dass in dem Fall, in dem y-x größer dann MAX_VALUE Sie nicht überlaufen.

0

ein >>> Bediener füllt die oberen Bits mit Null, im Gegensatz zu >>, die das Vorzeichenbit in die oberen bits.so bitweise Operator erstreckt >> hilfreich:

public static int mid(int x, int y){ 
    int midpoint = (x>>1) + (y>>1); 

    if((x&0b1)/0b1==1&&(y&0b1)/0b1==1){ 
     midpoint++; 
    } 

    return midpoint; 
} 

zum Beispiel: 1111 1110 (decimal -2) + 0000 0001 (dezimal 1) = 1111 1111 (dezimal -1)

1111 1111 (dezimal -1) >> 1 = 1111 1111 (dezimal -1)

während

1111 1111 (dezimal -1) >>> 1 = 0111 1111 (dezimal 127)

(Java-Typ 'Integer' ist 4 Bytes, hier nur zur Veranschaulichung)

Ich denke, das nützlich sein kann, zu verstehen, das Ergebnis;

+0

Ok ich sehe jetzt den Unterschied in diesen Operatoren, aber selbst mit >> scheint es zu Überlauf. Die Mitte von Integer.MAX_VALUE und Integer.MAX_VALUE sollte Integer sein.MAX_VALUE ist jedoch -1, und für Mitte (MIN_VALUE, MIN_VALUE) zeigt 0. – user7466895

+0

können Sie versuchen, Int Midpoint = (x >> 1) + (y >> 1); ', natürlich, Integer.MAX_VALUE und Integer .MAX_VALUE ist Integer.MAX_VALUE - 1 –

+0

Ich habe die Antwort editiert. '(X & 0b1)/0b1' soll den letzten Bitcode bekommen –

1

Wie wäre es mit diesem?

public static int mid(int x, int y) { 
    return x/2 + y/2 + (x%2 + y%2)/2; 
} 
Verwandte Themen