Math.clz32()

Baseline 已廣泛支援

此特性已相當成熟,可在許多裝置和瀏覽器版本上使用。自 ⁨2015 年 7 月⁩以來,各瀏覽器均已提供此特性。

Math.clz32() 靜態方法返回數字的 32 位二進位制表示形式中前導零的位數。

試一試

// 00000000000000000000000000000001
console.log(Math.clz32(1));
// Expected output: 31

// 00000000000000000000000000000100
console.log(Math.clz32(4));
// Expected output: 29

// 00000000000000000000001111101000
console.log(Math.clz32(1000));
// Expected output: 22

語法

js
Math.clz32(x)

引數

x

一個數字。

返回值

x 的 32 位二進位制表示形式中前導零的位數。

描述

clz32 是 **CountLeadingZeros32 (32 位前導零計數) 的縮寫。

如果 x 不是數字,它會先轉換為數字,然後再轉換為 32 位無符號整數。

如果轉換後的 32 位無符號整數是 0,則返回 32,因為所有位都是 0。如果最高有效位是 1 (即數字大於或等於 231),則返回 0

此函式對於編譯為 JS 的系統特別有用,例如 Emscripten

示例

使用 Math.clz32()

js
Math.clz32(1); // 31
Math.clz32(1000); // 22
Math.clz32(); // 32

const 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

實現前導一計數等功能

目前,沒有用於“前導一計數”的 Math.clon (命名為“clon”,而不是“clo”,因為“clo”和“clz”非常相似,尤其對於非英語母語者而言)。但是,可以透過對數字的位進行取反,然後將結果傳遞給 Math.clz32 來輕鬆建立 clon 函式。這樣做之所以有效,是因為 1 的反碼是 0,反之亦然。因此,對位進行取反會反轉 0 的測量量 (來自 Math.clz32),從而使 Math.clz32 計數的是 1 的數量而不是 0 的數量。

考慮以下 32 位字

js
const a = 32776; // 00000000000000001000000000001000 (16 leading zeros)
Math.clz32(a); // 16

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

利用此邏輯,可以建立如下的 clon 函式

js
const clz = Math.clz32;

function clon(integer) {
  return clz(~integer);
}

此外,此技術還可以擴充套件為建立無跳轉的“尾隨零計數”函式,如下所示。ctrz 函式取整數與其二的補碼的按位與。根據二的補碼的工作原理,所有尾隨零都將轉換為 1,然後新增 1 時,它會一直進位直到遇到第一個 0 (原先是 1)。此位之後的所有位都保持不變,並且是原始整數位的反碼。因此,當與原始整數進行按位與時,所有高位都變為 0,可以使用 clz 來計數。尾隨零的數量,加上第一個 1 位,再加上由 clz 計算出的前導位,總共為 32。

js
function ctrz(integer) {
  integer >>>= 0; // coerce to Uint32
  if (integer === 0) {
    // skipping this step would make it return -1
    return 32;
  }
  integer &= -integer; // equivalent to `int = int & (~int + 1)`
  return 31 - clz(integer);
}

然後,我們可以如下定義“尾隨一計數”函式

js
function ctron(integer) {
  return ctrz(~integer);
}

這些輔助函式可以被製作成 asm.js 模組,以可能提高效能。

js
const countTrailsMethods = (function (stdlib, foreign, heap) {
  "use asm";
  const clz = stdlib.Math.clz32;

  // count trailing zeros
  function ctrz(integer) {
    integer = integer | 0; // coerce to an integer
    if ((integer | 0) == 0) {
      // skipping this step would make it return -1
      return 32;
    }
    // Note: asm.js doesn't have compound assignment operators such as &=
    integer = integer & -integer; // equivalent to `int = int & (~int + 1)`
    return (31 - clz(integer)) | 0;
  }

  // count trailing ones
  function ctron(integer) {
    integer = integer | 0; // coerce to an integer
    return ctrz(~integer) | 0;
  }

  // asm.js demands plain objects:
  return { ctrz: ctrz, ctron: ctron };
})(window, null, null);

const { ctrz, ctron } = countTrailsMethods;

規範

規範
ECMAScript® 2026 語言規範
# sec-math.clz32

瀏覽器相容性

另見