Soweit ich weiß, werden die meisten Compiler schnelle Division durch Multiplizieren und dann Bitverschiebung nach rechts tun. Zum Beispiel, wenn Sie this SO thread überprüfen, heißt es, dass, wenn Sie den Microsoft-Compiler bitten, Division durch 10 zu tun, wird der Dividend mit 0x1999999A multipliziert (was 2^32/10 ist) und dann das Ergebnis durch 2^32 dividieren (mit 32 Verschiebungen auf der rechten Seite).Schnelle Division auf GCC/ARM
So weit so gut.
Sobald ich die gleiche Abteilung von 10 auf ARM mit GCC getestet, obwohl, der Compiler tat etwas anderes. Zuerst multiplizierte es die Dividende mit 0x66666667 (2^34/10), dann teilte es das Ergebnis mit 2^34. Bisher ist es dasselbe wie Microsoft, außer dass ein höherer Multiplikator verwendet wird. Danach subtrahierte es jedoch (Dividend/2^31) vom Ergebnis.
Meine Frage: Warum auf der ARM-Version gibt es diese zusätzliche Subtraktion? Können Sie mir ein numerisches Beispiel geben, wo ohne diese Subtraktion das Ergebnis falsch sein wird?
Wenn Sie den erzeugten Code überprüfen möchten, ist es unten (mit meinen Kommentaren):
ldr r2, [r7, #4] @--this loads the dividend from memory into r2
movw r3, #:lower16:1717986919 @--moves the lower 16 bits of the constant
movt r3, #:upper16:1717986919 @--moves the upper 16 bits of the constant
smull r1, r3, r3, r2 @--multiply long, put lower 32 bits in r1, higher 32 in r3
asr r1, r3, #2 @--r3>>2, then store in r1 (effectively >>34, since r3 was higher 32 bits of multiplication)
asr r3, r2, #31 @--dividend>>31, then store in r3
rsb r3, r3, r1 @--r1 - r3, store in r3
str r3, [r7, #0] @--this stores the result in memory (from r3)
Es ist für negative Werte, Integer Division abgeschnitten, und nur Multiplikation und Verschiebung produzieren 'x/10 - 1' für negative' x'. (Angenommen arithmetische Rechtsverschiebung natürlich.) –
Ich kann sehen, dass, wenn ich -99/10 mit der Multiplikation/Shift-Methode mache ich als Ergebnis -10 erhalten. Aber wenn ich 1 davon subtrahiere, werde ich -11 bekommen, wenn das, was ich will, -9 ist, nicht wahr? –
Sie subtrahieren "-1", d. H. Sie fügen 1 hinzu. –