2 Stimmen

GMP Bit Shift funktioniert nicht bei negativen Zahlen

Ich habe diese Funktion bei php.net gefunden. Sie scheint bei positiven Zahlen zu funktionieren, schlägt aber bei negativen Zahlen fehl:

function gmp_shiftr($x,$n) { // shift right
  return(gmp_div($x,gmp_pow(2,$n)));
} 

echo -1 >> 8; //returns -1, presumably correctly
echo "<br />";
echo gmp_strval(gmp_shiftr(-1,8)); //returns 0, presumably incorrectly

Wie kann ich die Funktion so einrichten, dass sie mit Negativen funktioniert?

Ich habe zwei Ideen:

Vielleicht könnte ich etwas in der Art wie folgt machen

if (whatever) { $a >> $b} else{ gmp_shiftr($a, $b) }?

Oder vielleicht könnte ich etwas von den negativen Ergebnissen abziehen, je nach ihrem Wert?

Ich möchte nur den Wert, der >> geben würde, aber auch erhalten Sie es für >32bit Zahlen, wenn ich GMP verwenden.

1voto

Jim Lewis Punkte 41707

Die Betrachtung der GMP-Dokumentation für die Abteilungsroutinen gibt es eine Funktion

void mpz_tdiv_q_2exp (mpz_t q, mpz_t n, unsigned long int b)

das scheint das zu sein, was Sie wollen: eine arithmetische Rechtsverschiebung, die die n als ob es in Zweierkomplement dargestellt würde, und (ich denke) verschiebt es b Orte nach rechts. Leider scheint diese Ebene der API von PHP GMP nicht zur Verfügung gestellt zu werden.

Ich habe eine Bit-Dreh-Hack für die Vorzeichenerweiterung, wenn die Anzahl der Bits in der Darstellung unbekannt ist:

unsigned b; // number of bits representing the number in x
int x;      // sign extend this b-bit number to r
int r;      // resulting sign-extended number
int const m = 1U << (b - 1); // mask can be pre-computed if b is fixed

x = x & ((1U << b) - 1);  // (Skip this if bits in x above position b are already zero.)
r = (x ^ m) - m;

Da bitweises AND und XOR sind von PHP GMP unterstützt wird, können Sie möglicherweise die das funktionieren...

0voto

Adam Hupp Punkte 1363

Wenn man dies mathematisch betrachtet, macht es Sinn. gmp_shiftr macht -1/256, was, wenn man gegen Null rundet (der gmp-Standard), 0 ist.

Die ">>"-Methode funktioniert so, weil negative Zahlen in vorzeichenerweiterter Zweierkomplementform dargestellt werden.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X