Math.clz32()
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
語法
Math.clz32(x)
引數
x-
一個數字。
返回值
x 的 32 位二進位制表示形式中前導零的位數。
描述
clz32 是 **CountLeadingZeros32 (32 位前導零計數) 的縮寫。
如果 x 不是數字,它會先轉換為數字,然後再轉換為 32 位無符號整數。
如果轉換後的 32 位無符號整數是 0,則返回 32,因為所有位都是 0。如果最高有效位是 1 (即數字大於或等於 231),則返回 0。
此函式對於編譯為 JS 的系統特別有用,例如 Emscripten。
示例
使用 Math.clz32()
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 位字
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 函式
const clz = Math.clz32;
function clon(integer) {
return clz(~integer);
}
此外,此技術還可以擴充套件為建立無跳轉的“尾隨零計數”函式,如下所示。ctrz 函式取整數與其二的補碼的按位與。根據二的補碼的工作原理,所有尾隨零都將轉換為 1,然後新增 1 時,它會一直進位直到遇到第一個 0 (原先是 1)。此位之後的所有位都保持不變,並且是原始整數位的反碼。因此,當與原始整數進行按位與時,所有高位都變為 0,可以使用 clz 來計數。尾隨零的數量,加上第一個 1 位,再加上由 clz 計算出的前導位,總共為 32。
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);
}
然後,我們可以如下定義“尾隨一計數”函式
function ctron(integer) {
return ctrz(~integer);
}
這些輔助函式可以被製作成 asm.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 |
瀏覽器相容性
載入中…