2

この関数は php.net で見つけました。正の数では機能するようですが、負の数では失敗します:

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

ネガで機能するように機能を修正するにはどうすればよいですか?

私が持っている2つのアイデア:

多分私はの線に沿って何かをすることができます

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

または、その値に応じて、負の結果から何かを差し引くことができるかもしれません..?

>> が与える値を取得したいだけでなく、GMP を使用するときに 32 ビットを超える数値でも取得したいのです。

4

2 に答える 2

1

除算ルーチンのGMPドキュメントを見ると、関数があります

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

それはあなたが望むものかもしれません: 算術右シフトは n、2 の補数で表されているかのように扱い、(私は思うに)b右にシフトします。残念ながら、そのレベルの API は PHP GMP では公開されていないようです。

表現のビット数が不明な場合に符号拡張を行うための少しいじるハックを見つけました。

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;

ビットごとの AND と XORPHP GMP でサポートされているため、これを機能させることができるかもしれません...

于 2011-01-26T01:20:35.800 に答える
0

これを数学的に考えれば当然のことです。gmp_shiftr は -1/256 を実行しています。これは、ゼロに向かって丸めた場合 (gmp のデフォルト) は 0 です。

">>" メソッドは、負の数が符号拡張された 2 の補数形式で表されるため、そのように機能します。

于 2011-01-26T01:09:46.267 に答える