【发布时间】:2021-06-30 13:26:38
【问题描述】:
我想将包含在 byte[] 中的 short[] 的位分开,以便每个 short 的最高有效位排列在一个连续的块中(数组?行?),然后是每个 short 的下一位,所以在。 这是位布局如何变化的简明示例:
0101010101010101 0101010101010101
would become
0011001100110011 0011001100110011
or with 3 it would look like
0101010101010101 0101010101010101 0101010101010101
which would become
0001110001110001 1100011100011100 0111000111000111
我把它放在一个代码块中以保留换行符。
如果我可以单独处理每个位,这将很容易,但我必须使用位运算符,这使得它变得非常困难。
忽略数组中元素的数量不是基类型位长度的倍数的可能性,在这种情况下为 16,我想出了这个:
fixed(byte* inptr = sourcearray){ //the shorts in a byte[]
fixed(byte* outptr = destination){//the output byte[]
var insamples = (short*)inptr;
var outsamples = (ushort*)outptr;
var mask = (ushort)0b1000000000000000;
for(int i = 0, j = 0; i < numsamples; ++i, j += 16){
if(j >= numsamples){
j = 0;
mask >>= 1;
}
outsamples[i] = (ushort)((insamples[j] & mask) | ((insamples[j + 1] & mask) >> 1) | ((insamples[j + 2] & mask) >> 2) | ((insamples[j + 3] & mask) >> 3) |
((insamples[j + 4] & mask) >> 4) | ((insamples[j + 5] & mask) >> 5) | ((insamples[j + 6] & mask) >> 6) | ((insamples[j + 7] & mask) >> 7) |
((insamples[j + 8] & mask) >> 8) | ((insamples[j + 9] & mask) >> 9) | ((insamples[j + 10] & mask) >> 10) | ((insamples[j + 11] & mask) >> 11) |
((insamples[j + 12] & mask) >> 12) | ((insamples[j + 13] & mask) >> 13) | ((insamples[j + 14] & mask) >> 14) | ((insamples[j + 15] & mask) >> 15));
}
}
}
我正在使用的数组有 480 个短裤(960 字节)长,我很确定它可以满足我的要求,但是我无法编写相反的函数来将数组恢复到原始状态状态,到目前为止我没有任何意义,我需要它合理优化以最小化所需的处理,但它伤害了我的大脑。
在 C++ 中执行此操作可能会更好,但我希望完全管理程序。
【问题讨论】:
-
我在第一关就掉了下来:我不知道你是怎么把
0101 0101 0101 0101变成0000 1111 0000 1111的 -
这是每个半字节的第一位,然后是每个半字节的第二位,依此类推。
-
这里的另一个小问题...短是 16 位,因此永远不能有 5 个“半字节”。
-
所以要反转它,您将当前位移动到(TotalNibbles - 当前位迭代计数器 - currentnibble)或者我错过了什么?我也不明白为什么你在输入法中硬编码位置而不是计数。
-
我知道这只是一个例子,说明如果元素的数量不是类型中位数的倍数,任务将如何变得更加复杂。
标签: c# arrays bit-manipulation short