2016-07-28 25 views
0

ich durch die Fragen auf LeetCode Lesen und stieß auf mit diesem:Bitwise hinaus arbeitet auf Java aber nicht auf Ruby-

„Berechnen Sie die Summe von zwei ganzen Zahlen a und b, aber Sie sind nicht zu verwenden, erlaubt der Operator + und - "

Was ist eine häufige Frage im Internet.

Java-Lösung für diese Frage lautet:

public int getSum(int a, int b) { 
    while(b!=0){ 
     int c = a&b; 
     a=a^b; 
     b=c<<1; 
    } 
    return a; 
} 

der gut arbeitet. Aber der gleiche Code in Ruby:

def get_sum(a, b) 
    while b != 0 do 
     c = a & b; 
     a = a^b; 
     b = c << 1; 
    end 
    return a; 
end 

funktioniert nicht. Tatsächlich funktioniert es, wenn sowohl "a" als auch "b" positive Zahlen sind, aber nicht, wenn entweder "a" oder "b" eine negative Zahl ist. Ich vermute, dass das Problem mit der Verschiebung der Träger verbunden ist, aber ist es nicht auch in Java das gleiche? Habt ihr eine Idee was in Ruby anders ist?

Vielen Dank im Voraus.

+0

sehen [diese Frage] (http://stackoverflow.com/questions/15359807/signed-and-unsigned-integers-in-ruby) – samgak

+0

Nur als Randnotiz: warum Ihre Erwartung? Die Tatsache, dass Sie das gleiche Programm in zwei Sprachen schreiben können, bedeutet nicht, dass jedes Element und jeder Typ in beiden Sprachen die absolut gleiche Bedeutung hat **. Ich würde sogar sagen, dass "alles absolut gleich ist" eine eher außergewöhnliche Situation wäre. – GhostCat

Antwort

1

In Java kann eine Ganzzahl um eine feste Anzahl verschoben werden, bevor sie Null wird. Diese Anzahl von Malen ist die Größe oder Bitzahl des ganzzahligen Wertes (für int sind es 32 Bits).

So bricht Ihre Schleife in Java als b wird Null.

Jedoch gibt es in Ruby keine Begrenzung wie oft eine Zahl verschoben werden kann bevor sie Null wird, da es keine feste Bitzahl für eine Zahl in Ruby gibt.

Deshalb wird b groß (kann sein, bis wir keinen Speicher mehr haben).

Das ist es sollte nicht einmal mit positiven Zahlen arbeiten und in eine Endlosschleife gehen.

Um diese Endlosschleife zu unterbrechen, können Sie die Genauigkeit der Zahl begrenzen, indem Sie AND für jedes Ergebnis mit einer festen Genauigkeit übernehmen.

precision = 0xFFFF; 
b = (c << 1) & precision; 

Bei negativen Zahlen gibt es noch einen Flaschenhals.

Da FixNum keine feste Größe haben nimmt tatsächlich eine negative Zahl nach bitweise Operation eine positive Zahl zu sein, so auch wenn 1111 in 2-Komplement -1 rubin es für einen positiven Wert annimmt 15.