按照从最高有效到最低有效 C# 的顺序从 short[] 中分离位
Posted
技术标签:
【中文标题】按照从最高有效到最低有效 C# 的顺序从 short[] 中分离位【英文标题】:Separate bits from short[] in order of most to least significant C# 【发布时间】: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)或者我错过了什么?我也不明白为什么你在输入法中硬编码位置而不是计数。
我知道这只是一个例子,说明如果元素的数量不是类型中位数的倍数,任务将如何变得更加复杂。
【参考方案1】:
我不想回答自己的问题,但我刚刚发现了 System.Collections.BitArray 类,它允许我单独处理位,并在几分钟内将操作中的代码替换为:
for(int i = 0, j = 0, k = 0; i < inbits.Length; ++i, j += 16)
if(j >= inbits.Length) j = ++k;
_outbitsout[i] = inbits[j];
并反转该操作:
var stride = inbits.Length/16;
for(int i = 0, j = 0, k = 0; i < inbits.Length; ++i, j += stride)
if(j >= inbits.Length) j = ++k;
_outbitsin[i] = inbits[j];
【讨论】:
以上是关于按照从最高有效到最低有效 C# 的顺序从 short[] 中分离位的主要内容,如果未能解决你的问题,请参考以下文章