web-dev-qa-db-ja.com

JavaScriptの符号なし整数

私はIPアドレス情報を処理するページで作業していますが、整数が署名されているという事実に窒息しています。ビット単位の演算子を使用して速度を上げていますが、64番目のビット(符号付き/符号なしフラグ)が混乱しています。

Javascriptで数値を強制的に符号なしにする方法はありますか?サブネットが30を超えるか、2未満になるまで、正常に動作するようです。

これを試して:

<html>
<body>

<script type='text/javascript'>
document.write( (1 << 30) +"<br/>");
document.write( (1 << 31) +"<br/>");
document.write( (1 << 32) +"<br/>");
</script>

</body>
</html>

結果:

1073741824 -2147483648 1

37
bradlis7
document.write( (1 << 31) +"<br/>");

<<演算子は、符号付き32ビット整数(倍精度浮動小数点のネイティブの数値ストレージから変換)で動作するように定義されています。したがって、1<<31は負の数になる必要があります。

符号なし32ビット整数を使用して機能するJavaScript演算子は、>>>のみです。これを利用して、他のビット演算子で作業してきた符号付き整数を、符号なし整数に変換できます。

document.write(( (1<<31)>>>0 )+'<br />');

その間:

document.write( (1 << 32) +"<br/>");

すべてのシフト操作はシフトの最下位5ビットのみを使用するため(JavaScriptおよびその他のCライクな言語でも)動作しません。 <<32<<0と等しい、つまり変化なし。

78
bobince

>>の代わりに>>>を使用して、符号拡張シフトの代わりに符号なし右シフトを取得します。他のすべてのビット演算子は、intが署名されているかどうかに関係なく同じように動作します。

「サブネット...が2未満の場合」を壊すコードが心配です。整数の符号付きとは関係のないバグがあるようです。

9
moonshadow

ダグラス・クロックフォードは、ビット演算子がjavascriptの悪い部分の1つであると考えています。

Javaでは、ビット演算子は整数で機能します。 JavaScriptには整数がありません。倍精度の浮動小数点数のみがあります。したがって、ビット演算子は、数値オペランドを整数に変換し、ビジネスを行ってから、元に戻します。ほとんどの言語では、これらの演算子はハードウェアに非常に近く、非常に高速です。 JavaScriptでは、それらはハードウェアから非常に遠く、非常に遅いです。 JavaScriptは、ビット操作を行うためにめったに使用されません。

-ダグラス・クロックフォード、「JavaScript:The Good Parts」、付録B、ビット単位演算子(強調を追加)

ビットごとの演算子が本当にロジックを高速化していると確信していますか?

9
Artem Latyshev

Javascriptには整数がありません。すべての数値は実際には倍精度です。

MozillaによるJavascript 1.5 Reference は、32ビットの数値に対してビット単位の操作のみを安全に使用できることを示唆しています。

6
Georg Schölly

以下は、ipv4アドレスをjavascriptの符号なし整数との間で変換する2つの関数です。

function ip2long(ip) {
    var ipl=0;
    ip.split('.').forEach(function( octet ) {
        ipl<<=8;
        ipl+=parseInt(octet);
    });
    return(ipl >>>0);
}

function long2ip (ipl) {
    return ( (ipl>>>24) +'.' +
        (ipl>>16 & 255) +'.' +
        (ipl>>8 & 255) +'.' +
        (ipl & 255) );
}
3
Francis Turner

どんなIPアドレスを持っていますか? IPv4は32ビットアドレスのみを使用するため、JavaScriptで問題ありません(doubleを使用すると 52ビット整数部 が得られます)。 IPv6は128ビットアドレスを使用するため、アレイを使用する必要があります。私の推測では、他の何かが壊れているということです。

[編集]内部データ型として2つのintの配列を使用する小さなライブラリを構築します。

0
Aaron Digulla