## 在循环中使用Math.pow()和Math.place()调用简化函数内容来源于 Stack Overflow，并遵循CC BY-SA 3.0许可协议进行翻译与使用

• 回答 (2)
• 关注 (0)
• 查看 (83)

```function x(a, b, c) {
rv = Math.floor(a * Math.pow(2, b));

for (i = 1; i < c; i++) {
rv += Math.floor(a * Math.pow(1.2, b + i));
}

return rv;
}```

### ⛓️注释指数：

```let exp = Math.pow(1.2, b);

for (let i = 1; i < c; ++i) {
exp  *= 1.2;
rv += Math.floor(a * exp);
}```

### 按位非运算符的🤖地板(~)：

```console.log(`Math.floor(4.01)  =  \${ Math.floor(4.01) }`);
console.log(`Math.floor(4.99)  =  \${ Math.floor(4.99) }`);
console.log(`Math.floor(-4.01) = \${ Math.floor(-4.01) }`);
console.log(`Math.floor(-4.99) = \${ Math.floor(-4.99) }`);

console.log(`~~4.01  =  \${ ~~4.01 }`);
console.log(`~~4.99  =  \${ ~~4.99 }`);
console.log(`~~-4.01 = \${ ~~-4.01 }`);
console.log(`~~-4.99 = \${ ~~-4.99 }`);

console.log(`Math.floor(2147483647.99) = \${ Math.floor(2147483647.99) }`);
console.log(`Math.floor(2147483648.01) = \${ Math.floor(2147483648.01) }`);
console.log(`~~2147483647.99 = \${ ~~2147483647.99 }`);
console.log(`~~2147483648.01 = \${ ~~2147483648.01 }`);```
```.as-console-wrapper {
max-height: 100vh !important;
}```

### 带左移位运算符的🤖Base2指数：

```for (let i = 0; i <= 31; ++i) {
console.log(`Math.pow(2, \${ i }) === 2 << (\${ i } - 1)? \${ Math.pow(2, i) === 2 << (i - 1) ? 'Yes' : 'No'}.` );
}```
```.as-console-wrapper {
max-height: 100vh !important;
}```

### ➰使用WITH循环：

```while (--c) {
exp *= 1.2;
rv += ~~(a * exp);
} ```

### 💨最终结果：

```function original(a, b, c) {
rv = Math.floor(a * Math.pow(2, b));

for (i = 1; i < c; i++) {
rv += Math.floor(a * Math.pow(1.2, b+i));
}

return rv;
}

function faster(a, b, c) {
let rv = ~~(a * (2 << (b - 1)));
let exp = Math.pow(1.2, b);

while (--c) {
exp *= 1.2;
rv += ~~(a * exp);
}

return rv;
}

const expected = original(2, 2, 113);
const actual = faster(2, 2, 113);
const ok = expected === actual ;

if (ok) {
// BEFORE:

const t0b = performance.now();

for (let i = 0; i < 100000; ++i) {
original(2, 2, 113);
}

const tb = performance.now() - t0b;

// AFTER:

const t0a = performance.now();

for (let i = 0; i < 100000; ++i) {
faster(2, 2, 113);
}

const ta = performance.now() - t0a;

console.log(` BEFORE = \${ tb }s`);
console.log(`  AFTER = \${ ta }s`);
console.log(`SPEEDUP = \${ Math.round(100 * tb / ta) / 100 } = \${ Math.round((1 - ta / tb) * 10000) / 100 }% faster!`);

} else {
console.log(`Faster version = \${ actual } does not return the same as before = \${ expected }`);
}```
```.as-console-wrapper {
max-height: 100vh !important;
}```

### 📜循环展开：

```function faster (a, b, c) {
let rv = a * (2 << (b - 1));
let exp = Math.pow(1.2, b);

const r = c % 4;

if (r === 0) {
exp *= 1.728;
rv += a * a * a * exp;
} else if (r === 1) {
c += 3;
} else if (r === 2) {
exp *= 1.2;
rv += a * exp;
c += 2;
} else if (r === 3) {
exp *= 1.44;
rv += a * a * exp;
c += 1;
}

a = Math.pow(a, 4);
c /= 4;

while (--c) {
exp *= 2.0736;
rv += a * exp;
}

return rv;
}```

```function original(a, b, c) {
rv = Math.floor(a * Math.pow(2, b));

for (i = 1; i < c; i++) {
rv += Math.floor(a * Math.pow(1.2, b+i));
}

return rv;
}

function faster(a, b, c) {
let rv = ~~(a * (2 << (b - 1)));
let exp = Math.pow(1.2, b);

const r = c % 4;

if (r === 0) {
exp *= 1.2;
rv += ~~(a * exp);
exp *= 1.2;
rv += ~~(a * exp);
exp *= 1.2;
rv += ~~(a * exp);
} else if (r === 1) {
c += 3;
} else if (r === 2) {
exp *= 1.2;
rv += ~~(a * exp);
c += 2;
} else if (r === 3) {
exp *= 1.2;
rv += ~~(a * exp);
exp *= 1.2;
rv += ~~(a * exp);
c += 1;
}

c /= 4;

while (--c) {
exp *= 1.2;
rv += ~~(a * exp);
exp *= 1.2;
rv += ~~(a * exp);
exp *= 1.2;
rv += ~~(a * exp);
exp *= 1.2;
rv += ~~(a * exp);
}

return rv;
}

const expected = original(2, 2, 113);
const actual = faster(2, 2, 113);
const ok = expected === actual;

if (ok) {
// BEFORE:

const t0b = performance.now();

for (let i = 0; i < 100000; ++i) {
original(2, 2, 113);
}

const tb = performance.now() - t0b;

// AFTER:

const t0a = performance.now();

for (let i = 0; i < 100000; ++i) {
faster(2, 2, 113);
}

const ta = performance.now() - t0a;

console.log(` BEFORE = \${ tb }s`);
console.log(`  AFTER = \${ ta }s`);
console.log(`SPEEDUP = \${ Math.round(100 * tb / ta) / 100 } = \${ Math.round((1 - ta / tb) * 10000) / 100 }% faster!`);

} else {
console.log(`Faster version = \${ actual } does not return the same as before = \${ expected }`);
}```
```.as-console-wrapper {
max-height: 100vh !important;
}```

```function x (a, b, c) {
var rv = Math.floor(a * Math.pow(2, b))
var multiplier = Math.pow(1.2, b + 1)
for (i = 1; i < c; i++) {
rv += Math.floor(a * multiplier);
multiplier *= 1.2
}
return rv;
}```