问题
不用加减乘除运算符,求整数的7倍
思路
当需要进行避免使用加减乘除的数学运算的时候,通常的方法有:位运算、Eval/Function 传参 hack、进制转换配合字符串转换操作等等,我们参考题目来源中提到的几种方式以及其他大佬们提供的解法来看下这道题。
-
位运算
位运算加法 - 连续7次相加
首先看下位运算常用的计算方式
从上面的表可以看出一种实现简单的多位二进制整数加法的算法如下:
m 和 n 是两个二进制整数,求 m + n
- 用与运算求 m 和 n 共同为 “1” 的位: m' = m & n
- 用异或运算求 m 和 n 其中一个为 “1” 的位: n' = m ^ n
- 如果 m' 不为 0,那么将 m' 左移一位(进位),记 m = m' << 1,记 n = n',跳回到步骤 1
- 如果 m' 为 0,那么 n' 就是我们要求的结果。
function bitAdd(m, n){
while(m){
[m, n] = [(m & n) << 1, m ^ n];
}
return n;
}
bitAdd(7, 7);
//14
加法计算出来,那么计算7点倍数就简单了。
function multiply7(num){
let sum = 0;
for(var i = 0; i < 7; i++){
sum = bitAdd(sum, num);
}
return sum;
}
multiply7(2); //14
for循环中存在‘+’,所以我们可以使用数组来代替
function multiply7(num){
let sum = 0;
// 得到 [empty × 7]
let extent = new Array(7);
while(extent.length){
sum = bitAdd(sum, num);
extent.shift();
}
return sum;
}
multiply7(2);
//14
使用位运算加法 8+(-1)来求7的倍数
let multiply7 = (num) => bitAdd(num << 3, -num);
multiply7(2); //14
题目中不能使用‘-’运算符,改造上面代码,使用‘~’来代替(num * -1)
let multiply7 = (num) => bitAdd(num << 3, bitAdd(~num,1));
multiply7(2); //14
-
hack
在javascript中,我们可以使用字节码来代替''+ - * / ''等运算符
let multiply7_1 = (num) =>
new Function(["return ",num,String.fromCharCode(42),"7"].join(""))();
let multiply7_2 = (num) =>
eval([num,String.fromCharCode(42),"7"].join(""));
setTimeout(["window.multiply7_3=(num)=>(7",String.fromCharCode(42),"num)"].join(""))
multiply7_1(2);
multiply7_2(2);
multiply7_3(2);
// 14
-
进制转换配合字符串转换操作
参考位运算我们进行一下思考:二进制整数向左位移一位、末尾补0,可以得到其2倍值;十进制整数向左位移一位、末尾补0,可以得到其10倍值;那么我们也可以依此法来进行七进制整数进位补0,来得到7倍值!
let multiply7_4 =
(num)=>parseInt([num.toString(7),'0'].join(''),7);
multiply7_4(2);// 14
知识点
- 位运算
- 补码
- 字节码
- 函数构造器 constructor
- eval 方法
- setTimeout 方法
- toString 和 parseInt 在进制操作上的方法
网友评论