java实现次方的运算_javascript位运算技巧

本文探讨了在JavaScript中由于浮点运算精度问题而导致的挑战,并指出虽然有人建议避免使用位运算,但精通JS的开发者可以巧妙利用位运算提高效率。文章列举了10个位运算的应用场景,包括利用左移运算符快速计算2的次方,通过位运算判断奇偶性和数值的布尔转换,以及进行数值取整和交换等。
摘要由CSDN通过智能技术生成

4e56b67a7cd1bbcb5a98753b4dcc311d.png
内容来源于 https:// juejin.cn/post/68449040 32146817038#heading-3 ,这里做整理收录

JavaScript 中最臭名昭著的 Bug 就是 0.1 + 0.2 !== 0.3,因为精度的问题,导致所有的浮点运算都是不安全的,具体原因可详见《0.1 + 0.2不等于0.3?为什么JavaScript有这种“骚”操作?》。


因此,之前有大牛提出,不要在 JS 中使用位运算:Javascript 完全套用了 Java 的位运算符,包括按位与&、按位或|、按位异或^、按位非~、左移<<、带符号的右移>>和用0补足的右移>>>

这套运算符针对的是整数,所以对 JavaScript 完全无用,因为 JavaScript 内部,所有数字都保存为双精度浮点数。如果使用它们的话,JavaScript 不得不将运算数先转为整数,然后再进行运算,这样就降低了速度。而且"按位与运算符" &同"逻辑与运算符" &&,很容易混淆。

但是在我看来,如果对 JS 的运用达到炉火纯青的地步,能避开各种“Feature”的话,偶尔用一下位运算符也无所谓,还能提升运算性能,毕竟直接操作的是计算机最熟悉的二进制。


位运算的原理可以参考这篇文章 《位运算符在JS中的妙用》


1. 使用左移运算符 << 迅速得出2的次方

1 << 2  // 4, 即 2的2次方
1 << 10 // 1024, 即 2的10次方

// 但是要注意使用场景, 非1的数字,会改变首位的正负
a = 2e9;   // 2000000000
a << 1;    // -294967296


2. 使用 ^ 切换变量 0 或 1

// --- before ---
// if 判断
if (toggle) {
    toggle = 0;
} else {
    toggle = 1;
}
// 三目运算符
togle = toggle ? 0 : 1;

// --- after ---
toggle ^= 1;


3. 使用 & 判断奇偶性
偶数 & 1 = 0
奇数 & 1 = 1

console.log(7 & 1);    // 1
console.log(8 & 1) ;   // 0


4. 使用 !! 将数字转为布尔值
所有非0的值都是true,包括负数、浮点数:

console.log(!!7);       // true
console.log(!!0);       // false
console.log(!!-1);      // true
console.log(!!0.71);    // true


5. 使用~>><<>>>|来取整
相当于使用了 Math.floor()

console.log(~~11.71)     // 11
console.log(11.71 >> 0)  // 11
console.log(11.71 << 0)  // 11
console.log(11.71 | 0)   // 11
console.log(11.71 >>> 0) // 11

e49d5d5257400c61a2d1c35ec2357e17.png


6. 使用^来完成值交换
这个符号的用法前面提到过,下面介绍一些高级的用法,在 ES6 的解构赋值出来之前,用这种方式会更快(但必须是整数):

// --- before ---
let temp = a; a = b; b = temp; // 传统,但需要借助临时变量
b = [a, a = b][0] // 借助数组

// --- after ---
let a = 7
let b = 1
a ^= b
b ^= a
a ^= b
console.log(a)   // 1
console.log(b)   // 7

[a, b] = [b, a]; // ES6,解构赋值


7. 使用^判断符号是否相同

 (a ^ b) >= 0; //  true 相同; false 不相同  复制代码

b3738060da29a0c207515393678dafa6.png


8. 使用^来检查数字是否不相等

 // --- before --- 
if (a !== 1171) {...};  
// --- after --- 
if (a ^ 1171) {...};  复制代码

d094a7aee720e4727656eb2c9b80815c.png


9. n & (n - 1),如果为 0,说明 n 是 2 的整数幂

0f6c490e9d2f4a94b2af05c338ebbcc8.png


10. 使用 A + 0.5 | 0 来替代 Math.round()

546c8dd872859077a976946ba377d51d.png


如果是负数,只需要-0.5

779d3103b5aa539440c4019a25d1ccf8.png
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值