自定义Math.abs()函数为何对带小数的数值取整近似?
自定义补码实现的abs函数为何会对小数产生取整近似?
我用补码方式实现了一个模拟Math.abs()的自定义函数,但发现它会对带小数的数值进行取整,比如输入-214.45返回214,输入-2745.892返回2745。函数代码如下:
function abs(x: number) { return x & (1 << 63) ? ~x + 1 : x; }
函数通过判断符号位决定是否取反,想知道为什么会出现这种取整问题?
原因很简单——你混淆了JavaScript/TypeScript中浮点数和整数位操作的特性:
- JavaScript/TypeScript的
number类型本质是IEEE 754双精度浮点数,不是固定长度的整数类型,它可以表示小数。 - 位操作符(
&、~)在执行时,会先把number类型的值强制转换为32位有符号整数,转换规则是直接截断小数部分,只保留整数位。 - 以
-214.45为例:- 执行
x & (1 << 63)时,-214.45先被转成32位整数-214; - 符号位判断为真,执行
~x + 1,对-214做补码取反得到214; - 最终返回的是整数
214,完全丢失了原有的小数部分。
- 执行
而原生的Math.abs()是直接对浮点数进行运算,不会触发32位整数转换,因此能正确保留小数位,比如Math.abs(-214.45)会返回214.45。
内容的提问来源于stack exchange,提问作者clapmemereview
相关产品推荐
相关产品推荐

