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 |
浏览器兼容性
加载中…