From 33058f2b292b3a581333bdfb21b8f671898c5060 Mon Sep 17 00:00:00 2001 From: Peter Bengtsson Date: Tue, 8 Dec 2020 14:40:17 -0500 Subject: initial commit --- .../reference/global_objects/math/clz32/index.html | 181 +++++++++++++++++++++ 1 file changed, 181 insertions(+) create mode 100644 files/ja/web/javascript/reference/global_objects/math/clz32/index.html (limited to 'files/ja/web/javascript/reference/global_objects/math/clz32/index.html') diff --git a/files/ja/web/javascript/reference/global_objects/math/clz32/index.html b/files/ja/web/javascript/reference/global_objects/math/clz32/index.html new file mode 100644 index 0000000000..d5b390382e --- /dev/null +++ b/files/ja/web/javascript/reference/global_objects/math/clz32/index.html @@ -0,0 +1,181 @@ +--- +title: Math.clz32() +slug: Web/JavaScript/Reference/Global_Objects/Math/clz32 +tags: + - ECMAScript 2015 + - JavaScript + - Math + - Method + - Reference +translation_of: Web/JavaScript/Reference/Global_Objects/Math/clz32 +--- +
{{JSRef}}
+ +

Math.clz32() 関数は、引数として与えられた数値の 32 ビットバイナリ表現での先頭の 0 の個数を返します。

+ +
{{EmbedInteractiveExample("pages/js/math-clz32.html")}}
+ + + +

構文

+ +
Math.clz32(x)
+ +

引数

+ +
+
x
+
数値。
+
+ +

返値

+ +

与えられた数値の32ビットバイナリ表現での先頭の 0 の個数。

+ +

解説

+ +

"clz32" は CountLeadingZeroes32 の省略形です。

+ +

x が数値でない場合、まず数値に変換され、32ビット符号なし整数値に変換されます。

+ +

変換された 32 ビット符号なし整数値が 0 の場合、すべてのビットが 0 であるため、32 を返します。

+ +

この関数は Emscripten のような JS にコンパイルするシステムに対して特に役に立ちます。

+ +

先頭の1を数える

+ +

現在のところ、 "Count Leading Ones" を表す Math.clon はありません ("clo" ではなく "clon" と名付けられています、なぜなら "clo" と "clz" は特に英語を話さない人にとっては似すぎているからです)。しかし、 clon 関数は、数値のビットを逆数にして、その結果を Math.clz32 に渡すことで簡単に作ることができます。 1 の逆数は 0 であり、その逆も同様です。このように、ビットを逆数にすると、測定された 0 の量が (Math.clz32 からの) 逆数になり、 Math.clz32 はゼロの数を数えるのではなく、1 の数を数えるようになります。

+ +

以下の32ビットワード値を想定してみます。

+ +
var a = 32776;   // 00000000000000001000000000001000 (16 leading zeros)
+Math.clz32(a);   // 16
+
+var b = ~32776;  // 11111111111111110111111111110111 (32776 inversed, 0 leading zeros)
+Math.clz32(b);   // 0 (this is equal to how many leading one's there are in a)
+ +

この論理を使用すると、 clon 関数は次のように作成することができます。

+ +
var clz = Math.clz32;
+function clon(integer){
+    return clz(~integer);
+}
+
+ +

さらに、この技術を拡張して、以下に示すようなジャンプレスの「Count Trailing Zeros」と「Count Trailing Ones」関数を作成することができます。以下の ctrz 関数は、すべての上位ビットを最も低いビットで埋め、そのビットを否定して上位のセットビットをすべて消去するので、clz が使用できます。

+ +
var clz = Math.clz32;
+function ctrz(integer){ // count trailing zeros
+    // 1. fill in all the higher bits after the first one
+    integer |= integer << 16;
+    integer |= integer << 8;
+    integer |= integer << 4;
+    integer |= integer << 2;
+    integer |= integer << 1;
+    // 2. Now, inversing the bits reveals the lowest bits
+    return 32 - clz(~integer) |0; // `|0` ensures integer coercion
+}
+function ctron(integer){ // count trailing ones
+    // No shift-filling-in-with-ones operator is available in
+    // JavaScript, so the below code is the fastest
+    return ctrz(~integer);
+    /* Alternate implementation for demonstrational purposes:
+       // 1. erase all the higher bits after the first zero
+       integer &= (integer << 16) | 0xffff;
+       integer &= (integer << 8 ) | 0x00ff;
+       integer &= (integer << 4 ) | 0x000f;
+       integer &= (integer << 2 ) | 0x0003;
+       integer &= (integer << 1 ) | 0x0001;
+       // 2. Now, inversing the bits reveals the lowest zeros
+       return 32 - clon(~integer) |0;
+    */
+}
+
+ +

これらのヘルパー関数を ASM.JS モジュールに入れます。そして、そうすれば、真のパフォーマンスの傑作ができあがります。このような状況は、まさに ASM.JS のために設計されたものです。

+ +
var countTrailsMethods = (function(stdlib, foreign, heap) {
+    "use asm";
+    var clz = stdlib.Math.clz32;
+    function ctrz(integer) { // count trailing zeros
+        integer = integer | 0; // coerce to an integer
+        // 1. fill in all the higher bits after the first one
+        // ASMjs for some reason does not allow ^=,&=, or |=
+        integer = integer | (integer << 16);
+        integer = integer | (integer << 8);
+        integer = integer | (integer << 4);
+        integer = integer | (integer << 2);
+        integer = integer | (integer << 1);
+        // 2. Now, inversing the bits reveals the lowest bits
+        return 32 - clz(~integer) |0;
+    }
+    function ctron(integer) { // count trailing ones
+        integer = integer | 0; // coerce to an integer
+        return ctrz(~integer) |0;
+    }
+    // unfourtunately, ASM.JS demands slow crummy objects:
+    return {a: ctrz, b: ctron};
+})(window, null, null);
+var ctrz = countTrailsMethods.a;
+var ctron = countTrailsMethods.b;
+ +

+ +

Math.clz32() の使用

+ +
Math.clz32(1);           // 31
+Math.clz32(1000);        // 22
+Math.clz32();            // 32
+
+var stuff = [NaN, Infinity, -Infinity, 0, -0, false, null, undefined, 'foo', {}, []];
+stuff.every(n => Math.clz32(n) == 32);  // true
+
+Math.clz32(true);        // 31
+Math.clz32(3.5);         // 30
+ +

ポリフィル

+ +

以下のポリフィルが最も効果的です。

+ +
if (!Math.clz32) Math.clz32 = (function(log, LN2){
+  return function(x) {
+    // Let n be ToUint32(x).
+    // Let p be the number of leading zero bits in
+    // the 32-bit binary representation of n.
+    // Return p.
+    var asUint = x >>> 0;
+    if (asUint === 0) {
+      return 32;
+    }
+    return 31 - (log(asUint) / LN2 | 0) |0; // the "| 0" acts like math.floor
+  };
+})(Math.log, Math.LN2);
+
+ +

仕様書

+ + + + + + + + + + + + +
仕様書
{{SpecName('ESDraft', '#sec-math.clz32', 'Math.clz32')}}
+ +

ブラウザーの互換性

+ + + +

{{Compat("javascript.builtins.Math.clz32")}}

+ +

関連情報

+ + -- cgit v1.2.3-54-g00ecf