首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >JavaScript中2的快速最近幂?

JavaScript中2的快速最近幂?
EN

Stack Overflow用户
提问于 2014-11-17 03:43:48
回答 3查看 6.1K关注 0票数 15

有比以下表达式更快的替代方法吗?

代码语言:javascript
运行
复制
Math.pow(2,Math.floor(Math.log(x)/Math.log(2)))

也就是说,取2倍最接近(较小)的整数幂?我有这样的表达在一个内环。我怀疑它可能会快得多,考虑到一个可以从IEEE 754的双表示中提取尾数。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-03-15 00:32:22

使用ES6的Math.clz32(n)来计数32位整数的前导零:

代码语言:javascript
运行
复制
// Compute nearest lower power of 2 for n in [1, 2**31-1]:
function nearestPowerOf2(n) {
  return 1 << 31 - Math.clz32(n);
}

// Examples:
console.log(nearestPowerOf2(9));  // 8
console.log(nearestPowerOf2(33)); // 32

票数 20
EN

Stack Overflow用户

发布于 2016-01-31 06:23:32

这是另一种选择,有基准。虽然两者似乎是可比较的,但我喜欢地板或赛尔。

代码语言:javascript
运行
复制
function pow2floor(v) {
  var p = 1;
  while (v >>= 1) {
    p <<= 1;
  }
  return p;
}

function pow2ceil(v) {
  var p = 2;
  while (v >>= 1) {
    p <<= 1;
  }
  return p;
}

function MATHpow2(v) {
  return Math.pow(2, Math.floor(Math.log(v) / Math.log(2)))
}


function nearestPowerOf2(n) {
   return 1 << 31 - Math.clz32(n);
}

function runner(fn, val) {
  var res;
  for (var i = 0; i < 10000000; i++) {
    fn(val);
  }
  return
}

var then;
var source = 3000;

then = new Date().getTime();
var a = runner(pow2floor, source);
console.log("\n--- pow2floor ---");
console.log(" result: " + pow2floor(source));
console.log(" time: " + (new Date().getTime() - then) + " ms");

then = new Date().getTime();
var b = runner(MATHpow2, source);
console.log("\n--- MATHpow2 ---");
console.log(" result: " + MATHpow2(source));
console.log(" time: " + (new Date().getTime() - then) + " ms");

then = new Date().getTime();
var b = runner(nearestPowerOf2, source);
console.log("\n--- nearestPowerOf2 ---");
console.log(" result: " + nearestPowerOf2(source));
console.log(" time: " + (new Date().getTime() - then) + " ms");

// my results (results vary by system and browser)
//  pow2floor:       130 ms loser
//  MATHpow2:        147 ms loser
//  nearestPowerOf2: 47 ms clear winner!

票数 5
EN

Stack Overflow用户

发布于 2014-11-17 14:24:26

不幸的是,您需要一个与C函数frexp相当的函数。我所能找到的最好的是JSFiddle,它的代码使用Math.pow

除了当前的尝试之外,您还可以使用实际数据对几个备选方案进行基准测试:

  1. 从1.0开始,反复乘以2.0,直到它大于或等于输入,然后乘以0.5,直到它小于或等于输入。您需要对双量程末端的值进行特殊处理。
  2. 在双范围内存储两个的所有幂的升序值数组,并执行二进制搜索。

如果数据通常接近1.0,则第一个可能是最快的。第二个条件分支最多需要11个条件分支。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26965171

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档