位运算符如何去除数字的小数部分?

3

我看到很多人使用位运算符来去除小数部分或对数字进行四舍五入,但我想知道这实际上是如何工作的?

let a = 13.6 | 0; //a == 13
let b = ~~13.6; // b == 13

我曾经搜索过类似的问题,最好的答案是这个。在那里人们谈论效率、利弊。我对它的实现方式感兴趣。

除了无符号右移 >>> 之外的所有位运算都适用于有符号的32位整数。因此使用位运算将会把浮点数转换为整数。

因此使用位运算将会把浮点数转换为整数。 但是怎么实现呢?

你对整数和浮点数有什么理解?你想了解什么 - 是否对算法及其如何处理边缘情况感兴趣,是否正在寻找引擎实现,或者你想了解内存中的各个位发生了什么? - Bergi
你想知道RAM中的每个位是如何工作的吗?这就是我要找的内容。使用分数进行OR操作时,如何修剪其小数部分? - sujeet
1
好的。它不处理单个位。它将64位视为双精度浮点表示,并对它们进行数学运算以得出整数。 - Bergi
1
https://2ality.com/2012/02/js-integers.html - Bergi
1个回答

3
使用 | 运算符时,它的两个操作数会通过 NumberBitwiseOp 操作转换为整数。该操作会对这两个操作数调用 ToInt32 方法,其过程如下:

抽象操作 ToInt32 接受一个参数 argument,并将其转换为范围在 -231 到 231 - 1 之间的 232 个整数值中的一个。当调用时,它执行以下步骤:

  1. 令 number 为 ? ToNumber(argument)。
  2. 如果 number 是 NaN、+0、-0、+∞ 或 -∞,则返回 +0。
  3. 令 int 为与 number 同号且绝对值向下取整后的 Number 值。
  4. 令 int32bit 为 int modulo 2 ** 32。
  5. 如果 int32bit ≥ 2 ** 31,则返回 int32bit - 2 ** 32;否则返回 int32bit。
使用 ~ (或按位非)也是类似的,它会对其操作数调用 ToInt32 方法。
使用 x | 0 可以去掉 x 的小数部分(通过 ToInt32 方法),并且不会翻转任何位,因此其效果类似于去掉了小数部分。
使用 ~x 可以去掉 x 的小数部分,并翻转 所有 位。使用 ~~x 也是一样的,但会将位翻转 两次,因此其结果就像是原始表达式去掉小数部分而已。

我需要深入学习JS中的数字,实际上我已经尝试了很多次,但从未完全掌握:(。这是解开你的答案的唯一关键。:) - sujeet

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接