Java Integer类具有静态方法highestOneBit方法,该方法将返回一个单个一位的值,该值位于指定值中最高一位的位置,如果指定值本身等于零,则返回零。
例如,int 17的输入将返回16;因为17可以用二进制表示为10001,所以它将返回等于16的最左边的位。
在整数类中,它在Java文档中具有以下实现。
public static int highestOneBit(int i) {
// HD, Figure 3-1
i |= (i >> 1);
i |= (i >> 2);
i |= (i >> 4);
i |= (i >> 8);
i |= (i >> 16);
return i - (i >>> 1);
}
我只想知道以这种方式实现它背后的逻辑以及使用 shift 操作背后的逻辑。谁能给它一些启示。
前五行(i|=(i
为了简单起见,让我们假设<code>int</code>是8位。在这种情况下,代码如下:
public static int highestOneBit(int i) {
i |= (i >> 1);
i |= (i >> 2);
i |= (i >> 4);
return i - (i >>> 1);
}
现在,假设我们的值是128(
1000000
)。这是会发生的情况:
// i == 10000000
i |= (i >> 1); // i = 10000000 | 11000000 = 11000000
i |= (i >> 2); // i = 11000000 | 11110000 = 11110000
i |= (i >> 4); // i = 11110000 | 11111111 = 11111111
return i - (i >>> 1); // 11111111 - 01111111 = 10000000
现在,让我们尝试64(01000000):
// i == 01000000
i |= (i >> 1); // i = 01000000 | 00100000 = 01100000
i |= (i >> 2); // i = 01100000 | 00011000 = 01111000
i |= (i >> 4); // i = 01111000 | 00000111 = 01111111
return i - (i >>> 1); // 01111111 - 00111111 = 01000000
i|=
语句有助于计算与i
长度相同的一系列语句。例如,对于101011
,它计算111111
。我已经解释了它在这个答案中是如何工作的(我现在无法重新键入它,因为我在移动设备上)。
所以基本上,一旦你有了一串1,减法本身右移一位就得到了H.O.位。
111111 - (111111 >>> 1) = 111111 - 011111 = 100000
该算法计算给定的<code>i</code>,其二进制表示为:
0..01XXXXXXX...XXXX
价值
0..011111111...1111
这就是 5 |=
运算符所做的。
然后,在return语句中,它从中减去右移一位的值
0..001111111...1111
得到结果
0..010000000...0000
它是如何工作的:
第32位(最左边)可能的最高1位。假设输入数字的该位为1:
1XXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX
您或该值右移1<code>(i
11XXXXXX XXXXXXXX XXXXXXXX XXXXXXXX
然后,您或值右移2(i)的新值
1111XXXX XXXXXXXX XXXXXXXX XXXXXXXX
然后您或该值右移4的新值
(i
11111111 XXXXXXXX XXXXXXXX XXXXXXXX
然后你或那个新值,该值向右移动了 8
(i
11111111 11111111 XXXXXXXX XXXXXXXX
最后,您或该值右移16 <代码>的新值(I
11111111 11111111 11111111 11111111
如果最高的1位小于第32位,则这些操作仍将其右侧的所有位变为1,并将剩余的(较高的位)保持为0。
根据《联合法律法规》第15.19条: 如果左手操作数的提升类型是长的,那么只使用右手操作数的六个最低阶位作为移位距离。这就好像右边的操作数服从一个位逻辑AND运算符(§15.22.1),掩码值为0x3f(0b111111)。因此,实际使用的移位距离总是在0到63的范围内,包括在内。 我们可以在C#中找到同样的东西。在Python中,它将是6位而不是5位,但逻辑保持不变。 背后的理由是什么?对我来说
我正试图从现实中解决一个问题 “偶数总和” 但是我不能这样做。下面是问题。 即使是总和也是两个玩家的游戏。玩家将获得N个正整数序列并轮流进行。在每个回合中,玩家选择一个非空切片(连续元素的子序列),使得该切片中的值之和是偶数,然后删除切片并连接序列的其余部分。第一个无法做出合法举动的玩家将输掉比赛。 如果你和你的对手玩这场游戏,你想知道你是否能赢,假设你和对手都玩得很好。你先走。 写一个函数:
此方法的任务是从数组中移除要移除的值。剩下的元素应该只向数组的开头移动。(数组的大小不会改变。)由于数组现在少了一个元素,最后一个元素的位置应该用0填充。如果数组中有多个toRemove的匹配项,则只应移除第一个匹配项。方法没有返回值,如果数组没有元素,它应该只是没有效果。 解决方案: 我不明白这个算法是如何工作的。boolean的使用让我感到困惑,我觉得我不完全理解原始数据类型是做什么的,我知道
本文向大家介绍javascript背景时钟实现方法,包括了javascript背景时钟实现方法的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了javascript背景时钟实现方法。分享给大家供大家参考。具体如下: 以下是这个效果的全部代码。[最好从一个空页面开始] 说明:时钟显示的位置需要你修正TOP,LEFT参数来确定。TOP表示层距离显示器顶部的象素值,LEFT表示距离左侧的象素值。
问题内容: 在Java中,可以使用 AtomicMarkableReference 原子地更新对象引用以及标记位。 该javadoc的状态: 实施注意事项:此实现通过创建表示“装箱的” [reference,boolean]对的内部对象来维护可标记的引用。 根据在该类的Java 8源代码中可以看到的情况,这是正确的: 该类的get方法的设计背后是否有原因? 使用这种布尔数组(而不是返回值对)有什么
问题内容: 我正在使用JWT保护节点js URL https://github.com/auth0/express- jwt 要创建JWT令牌用户会话,我只需执行以下操作: 或在登录电话的情况下 每次调用受保护的URL时,我都会检查JWT中间件是否自动设置了该URL 。 现在我想知道: 1-调用sign()时,JWT令牌存储在哪里? 2-每次调用受保护的网址时,我都必须验证()令牌吗?如果是,为什