Math.clz32()

Math.clz32() 静态方法返回数字的 32 位二进制表示形式中前导零位数。

¥The Math.clz32() static method returns the number of leading zero bits in the 32-bit binary representation of a number.

Try it

语法

¥Syntax

js
Math.clz32(x)

参数

¥Parameters

x

一个号码。

返回值

¥Return value

x 的 32 位二进制表示中前导零位数。

¥The number of leading zero bits in the 32-bit binary representation of x.

描述

¥Description

clz32 是 CountLeadingZeros32 的缩写。

¥clz32 is short for CountLeadingZeros32.

如果 x 不是数字,则会先转换为数字,然后再转换为 32 位无符号整数。

¥If x is not a number, it will be converted to a number first, then converted to a 32-bit unsigned integer.

如果转换后的 32 位无符号整数是 0,则返回 32,因为所有位都是 0。如果最高有效位是 1(即数字大于或等于 231),则返回 0

¥If the converted 32-bit unsigned integer is 0, 32 is returned, because all bits are 0. If the most significant bit is 1 (i.e. the number is greater than or equal to 231), 0 is returned.

这个函数对于编译为 JS 的系统特别有用,比如 恩脚本

¥This function is particularly useful for systems that compile to JS, like Emscripten.

示例

¥Examples

使用 Math.clz32()

¥Using 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

实现 Count Leads 及其他

¥Implementing Count Leading Ones and beyond

目前,"数一数领先者" 还没有 Math.clon(命名为 "clon",而不是 "clo",因为 "clo" 和 "clz" 太相似了,特别是对于非英语国家的人来说)。然而,通过反转数字的位并将结果传递给 Math.clz32 可以轻松创建 clon 函数。这样做是可行的,因为 1 的倒数是 0,反之亦然。因此,反转位将反转测量的 0 数量(来自 Math.clz32),从而使 Math.clz32 计算 1 的数量而不是计算 0 的数量。

¥At present, there is no Math.clon for "Count Leading Ones" (named "clon", not "clo", because "clo" and "clz" are too similar especially for non-English-speaking people). However, a clon function can easily be created by inverting the bits of a number and passing the result to Math.clz32. Doing this will work because the inverse of 1 is 0 and vice versa. Thus, inverting the bits will inverse the measured quantity of 0's (from Math.clz32), thereby making Math.clz32 count the number of ones instead of counting the number of zeros.

考虑以下 32 位字:

¥Consider the following 32-bit word:

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 函数,如下所示:

¥Using this logic, a clon function can be created as follows:

js
const clz = Math.clz32;

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

此外,该技术可以扩展以创建无跳转 "计算尾随零" 功能,如下所示。ctrz 函数对整数与其补码进行按位与运算。根据补码的工作原理,所有尾随的零都将转换为一,然后在加 1 时,它会被结转,直到到达第一个 0(最初是 1)。所有高于该位的位保持不变,并且是原始整数位的倒数。因此,与原整数进行按位与时,所有高位都变成 0,可以与 clz 一起计数。尾随零的数量,加上第一个 1 位,加上 clz 计数的前导位,总计为 32。

¥Further, this technique could be extended to create a jumpless "Count Trailing Zeros" function, as seen below. The ctrz function takes a bitwise AND of the integer with its two's complement. By how two's complement works, all trailing zeros will be converted to ones, and then when adding 1, it would be carried over until the first 0 (which was originally a 1) is reached. All bits higher than this one stay the same and are inverses of the original integer's bits. Therefore, when doing bitwise AND with the original integer, all higher bits become 0, which can be counted with clz. The number of trailing zeros, plus the first 1 bit, plus the leading bits that were counted by clz, total to 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);
}

然后我们可以像这样定义一个 "计算尾随的个数" 函数:

¥Then we can define a "Count Trailing Ones" function like so:

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

这些辅助函数可以制作成 asm.js 模块,以提高潜在的性能。

¥These helper functions can be made into an asm.js module for a potential performance improvement.

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;

规范

Specification
ECMAScript Language Specification
# sec-math.clz32

¥Specifications

浏览器兼容性

BCD tables only load in the browser

¥Browser compatibility

也可以看看