Java的非标准位操作

时间:2016-02-27 00:34:04

标签: java

我有一个程序,我目前正在使用byte[]布尔数组,即每个元素都是01。我想我应该尝试使用按位运算来加速程序。

我需要解决的一个问题如下。例如,让

long a = 5 = "00101"(我不会在开头写下所有无趣的零) long b = 24 = "10100"。 (我不会在开头写下所有无趣的零)

我需要一个操作,O说,aOb占据a1的位置,取b的相应值连接它们,以便在这种情况下我们将

2 = "00010"。 (我不会在开头写下所有无趣的零)

a 00101 
O   ↓ ↓ <- pick bits pointed by `1` in a
b 10100 
    ↓ ↓
    1 0 -> concatenate selected bits -> 10

编辑: 试图澄清: 好的,我们从左边或右边经过a。如果我们遇到0,我们什么也没有。如果我们计算1,我们会将相应索引的值b。例如,从左侧开始,我们不会对两个0执行任何操作,然后我们找到1,因此我们从1获取相应的b,我们找到另一个0 1}}在a中并且什么都不做,然后我们在1中找到另一个a并从0中取出相应的b

修改 另一种说法就是这样:向右移a并读出值(这可能吗?)。如果是1,我们会将b向右移动,读取值,将其存储到结果变量r并向右移动r。如果是0,我们会将b转移到右侧,忘记值,不对r执行任何操作。

编辑: 我会详细说明目的,试图澄清我想做的事情。我们有一组布尔变量(比如说5与我们的例子一致)。变量b根据某些索引表示其状态的数组。变量1中的a代表我们系统中的布尔变量的索引,即我们示例中的2和4,这与某个布尔变量(比如第0个)有关。第2和第4个布尔变量的值构成与第0个变量关联的真值表的可能输入之一。

有什么建议吗?

编辑: 现在,我正在做的就是这个。假设我们有一个包含5个布尔变量的系统,索引为$ 0,1,2,3,4 $。假设第0个变量是第2个和第4个变量的函数,并且具有AND的真值表,即

2 | 4 |Output for 0

0 | 0 | 0
0 | 1 | 0
1 | 0 | 0
1 | 1 | 1

我总是以这种方式对表进行排序,所以我真的不需要表的左侧部分。该表的右侧部分实现为byte[]数组。为了找到输出,我只是将输入读取的整数表示作为二进制数。例如。输入10为2,因此我的输出是我的byte[]数组中索引2处的值。为了找到输入,我需要系统当前状态的一部分,它对应于有问题的变量,即0。也就是说,我想要第二个和第四个变量的值,按顺序读取。

因此:

byte[] c = new byte[]{1,0,1,0,0}; //Corresponds to b above
int[] ind = new int[]{2,4}; //Indices of c that we're interested in
byte[] table = new byte[]{0,0,0,1}; //The truth table
int j = 0; //Truth table index
for(int i = 0; i < ind.length; i++) {
     j += c[ind[i]]*(1 << (ind.length - 1 - i)) //Binary to integer
}
//Output is table[j] 

4 个答案:

答案 0 :(得分:3)

顺便说一下,“10100”是20而不是24



And the client requests with the url. I use JQuery and the code is

$.get({ url: "http://address!!!!", type: "GET", success: function(result) { console.log("yay"); console.log(result); }, error: function (err) { console.log(err); }, });

If the above client code does not work, then try to add 'dataType: "json"'

你仍然以循环结束,所以这只会节省内存。

答案 1 :(得分:2)

这只是伪代码,因此无法保证完整性和正确性。

r = 0

for(int i=0; i<bits; i++) {
  condition = (a >> i) & 1;
  lookup    = (b >> i) & 1;
  if(condition == 1) {
    r = (r << 1) | lookup;
  }
}

鉴于这些意见......

a = 00101
b = 10100
bits = 5

算法表现如下。初始化结果。

r = 0

取最后一位,即i=0。为了做到这一点,请转移到位置i并使用和这样的操作踢出其余的数字:& 1。为ab执行此操作。然后检查过滤条件是否为真,在这种情况下,它意味着a在最后一位有1时。

i = 0
condition = (00101 >> 0) & 1 = 00101 & 1 = 00001 = 1
lookup    = (10100 >> 0) & 1 = 10100 & 1 = 00000 = 0
r         = (0 << 1) | 0 = 0 | 0 = 0 

i = 1
condition = (00101 >> 1) & 1 = 00010 & 1 = 00000 = 0
lookup    = (10100 >> 1) & 1 = 01010 & 1 = 00000 = 0
r         = 0 // no modification here

i = 2
condition = (00101 >> 2) & 1 = 00001 & 1 = 00001 = 1
lookup    = (10100 >> 2) & 1 = 00101 & 1 = 00001 = 1
r         = (1 << 1) | 1 = 2 | 1 = 3

可以使用两个函数清理代码,例如:

lastAt(i, x)   := (x >> i) & 1;
concatTo(r, v) := (r << 1) | v;

r = 0
for(int i=0; i<bits; i++) {
  if(lastAt(i, a) == 1) {
    r = concatTo(r, lastAt(i, b));
  }
}

答案 2 :(得分:1)

这些操作不太可能成为您计划的瓶颈。所以我的建议只是使用一系列布尔值 - 不要为了逐位操作而烦恼,它会让你的程序更难理解和修改。

如果您真的担心花在这些操作上的执行时间,请在尝试优化之前进行一些仔细的基准测试或分析。我的猜测是,通过修改代码,将显示没有任何好处。

答案 3 :(得分:-2)

你的描述含糊不清,但从默默无闻中可以看出,这根本不是一个按位操作。在这种情况下,我提供真值表的原始建议是有效的,事实上你应该如何实现它:使用表查找。