Javascript 隔离最左边的1位
我在搜索如何在二进制中分离最右边的位: 我得到了这个解决方案:Javascript 隔离最左边的1位,javascript,binary,Javascript,Binary,我在搜索如何在二进制中分离最右边的位: 我得到了这个解决方案: y = x & (-x) 因此: 但是现在,我想通过查找最左边的数字来计算一个数字的大小(但不是符号…) 我如何详细说明我的解决方案,以找到最左边的一点 示例: 10111100 01000100没有类似的O(1)位技巧来计算数字的大小。许多微处理器指令集都包含一个特殊的指令来“计算前导零”。在C语言家族中没有这样的运算符赋予JavaScript按位功能 唯一的O(1)选择是使用Math.floor(Math.log(n)
y = x & (-x)
因此:
但是现在,我想通过查找最左边的数字来计算一个数字的大小(但不是符号…)
我如何详细说明我的解决方案,以找到最左边的一点
示例:
101
11100
01
000100没有类似的O(1)位技巧来计算数字的大小。许多微处理器指令集都包含一个特殊的指令来“计算前导零”。在C语言家族中没有这样的运算符赋予JavaScript按位功能
唯一的O(1)选择是使用Math.floor(Math.log(n)/Math.LN2)
for ( var i = 0; i == Math.floor( Math.log( 1<<i ) / Math.LN2 ); ++ i ) ;
当然,对于其中任何一个,都必须按结果左移一位,以获得“最左边的1位”,而不是索引
EDIT:注意,基于
log
的实现返回-Infinity
为零,而mag
函数返回0
,这与1
的结果相同。如果您想考虑不存在最左边的1位的可能性,最好将其作为特例。我不认为Math.floor(Math.log(n)/Math.LN2)
是O(1),因为Math.log
不是基本操作
所以,下面的定理说你不能得到最左边的1位:
将字映射到字的函数可以用字并行加法、减法、and、or和not指令实现,当且仅当结果的每一位仅依赖于每个输入操作数右侧的位时
这个定理在《黑客的喜悦》(亨利·s·沃伦,Jr.)一书的第13页。为什么不直接使用
Math.log
?因为这个问题被标记为二进制。事实上,Math.log
可能是最好的方法。它不应该是:Math.pow(2,Math.log(1000)/Math.log(2))
?@RoyiNamir该pow
呼叫与我在“编辑”之前的最后一段中提到的左班次相同。请选择。(尽管使用pow
可以处理32位范围以外的数字,这是一个主要优势。)
for ( var i = 0; i == Math.floor( Math.log( 1<<i ) / Math.LN2 ); ++ i ) ;
var mag = function( n ) {
var acc = 0;
for ( var i = 16; i; i >>= 1 ) {
if ( n >> i ) {
n >>= i;
acc += i;
}
}
return acc;
};