2009-11-20 7 views
6

私は、JavaScriptで64ビット整数の循環左シフトを実行する必要があります。しかし:JavaScriptで64ビット(符号なし)整数のビット単位の回転をシミュレートするにはどうすればよいですか?

  • JavaScriptの番号ダブルス
  • あなたは< <と>>で始まり、>>>と〜とビットいじるの全て際JavaScriptが32ビット符号付き整数型に変換しますビジネス。そして、それが終わったら二倍に戻ります。おもう。
  • 私は看板を望んでいません。そして、私は間違いなく小数点ビットを望んでいません。しかし、私は間違いなく64ビットが欲しい。

64ビット値のビットごとの左回転を実行するにはどうすればよいですか?

+0

知っていますか? – Amber

+1

p.s. JavaScriptでこれをしないようにと教えてくれる人のためのダウンボーツ。役に立たない! JavaScriptがうまくいくようなことではないことを知っています。しかし、私はとにかくそれをする必要があります。 KTHXBAI。 – Jeff

+0

私はあなたを信じていませんが、JavaScriptが2倍に格納している場合は、64bit intではなく2倍です(符号に関係なく)。 –

答えて

12

64ビットの数値を上下半分に分けて保存してください。

hi_rot = ((hi << N) | (lo >>> (32-N))) & (0xFFFFFFFF)

lo_rot = ((lo << N) | (hi >>> (32-N))) & (0xFFFFFFFF)

N> = 32の場合、Nから32を引き、HIおよびLO交換、及びその後上記の操作を行いますN < 32が左Nを回転させます。

+0

私はこのやり方が好きですが、数字が署名されているという事実はどんな問題を引き起こすのでしょうか?最上位ビットには符号が格納されます。 – Jeff

+0

ああ、あなたは32歳未満だと言いました。 – Jeff

+1

この問題の唯一の問題は、ここでは '&(0xFFFFFFFF)'はノーオペレーションであることです。番号を符号なしにする場合は、代わりに '>>> 0'を使用してください。 –

4

私は、最も効率的な方法ではありませんが、数値をバイナリ形式(64ビット)の文字列に変換し、部分文字列を使用して最初にcharを移動し、最後に追加しますバイナリ形式をnumberに戻します。私は10進数をバイナリ形式に変換して文字列に変換する方法を理解することができます。

+0

私は投票を求めていると思いますか? :-) – Murali

+0

+1:それは本当に奇妙な問題へのハックな解決策です。 –

+2

ナー、それは私が望んでいる解決策の種類ではないとしても、正当な解決策です。あなたのためのdownvotesなし。 – Jeff

0

これは、内部で2つの32ビット整数を含むint64クラスを作成し、それらの間を移動することによってシフトを実行することだけです。

0

ここには値ベースの回転があります。

double d = 12345678901.0; 
// get high int bits in hi, and the low in 
int hi = (int)(d/16.0/16.0/16.0/16.0); 
int low = (int)d; 

int rot = 3; // thus * 8 
int newhi = (low >> (32 - rot)) | (hi << rot); 
int newlow = (hi >> (32 - rot)) | (low << rot); 

double newdouble = ((double)hi * 16.0 * 16.0 * 16.0 * 16.0) + (double)low; 
+0

これはC#のバージョンです。署名されたintのため、最後のステップは実際には期待どおりに動作しません。実際には、負の倍精度の2倍精度浮動小数点数型の場合でもうまくいかない可能性があります。 –

+0

特に、大量のバイトを変換する場合は、処理速度が遅すぎます。画像データであり、実用的な解決策ではない。 –

1

@Dougカリーはそれを置くとして、あなたはそれらの上にビット単位の演算を行い、その後、二つの数として64ビットの数値を表現する必要があります。私が使用したコードは次のとおりです。

//Constructor for a Long.. 
function Long(high, low) { 
    //note: doing "or 0", truncates to 32 bit signed 
    //big-endian 2's complement int.. 
    this._high = high | 0; 
    this._low = low | 0; 
} 
Long.prototype.rotateLeft = function(bits) { 
    var newHigh; 
    if(bits === 32){ //just switch high and low over in this case.. 
     newHigh = this._low; 
     this._low = this._high; 
     this._high = newHigh; 
    } else { 
     newHigh = (this._high << bits) | (this._low >>> (32-bits)); 
     this._low = (this._low << bits) | (this._high >>> (32-bits)); 
     this._high = newHigh; 
    } 
    return this; //for chaining.. 
}; 
//Rotates the bits of this word round to the right (max 32).. 
Long.prototype.rotateRight = function(bits) { 
    var newHigh; 
    if(bits === 32){ //just switch high and low over in this case.. 
     newHigh = this._low; 
     this._low = this._high; 
     this._high = newHigh; 
    } else { 
     newHigh = (this._low << (32-bits)) | (this._high >>> bits); 
     this._low = (this._high << (32-bits)) | (this._low >>> bits); 
     this._high = newHigh; 
    } 
    return this; //for chaining.. 
}; 

実行してみて、それを使用するには:console.log(new Long(0,1).rotateLeft(4));、その後_highと_lowの特性を検査します。

0

私はこれをしようとするだろう:あなたは、あなたのJavascriptが常に64ビットプラットフォーム上で実行されますことを確実に

function rotate(hi,lo,n) { 
    var N = n/%32; 
    if(Math.floor(n/32)%2) { 
     var hi_rot = ((hi << N) | (lo >>> (32-N))) & (~0); 
     var lo_rot = ((lo << N) | (hi >>> (32-N))) & (~0); 
    } else { 
     var hi_rot = ((lo << N) | (hi >>> (32-N))) & (~0); 
     var lo_rot = ((hi << N) | (lo >>> (32-N))) & (~0); 
    } 
    return (hi_rot<<32)+lo_rot; 
} 
関連する問題