我修改了答案。非常感谢你扩展了你的答案!我看起来是个不错的解决方案。通宵思考这个问题,我还发现了一种替代方法,它不需要定义类似术语的东西。我不确定是否应该将其作为备选答案发布,或者发布在评论或原始问题中?@Oriol Canela Xandri-如果您的方
我修改了答案。非常感谢你扩展了你的答案!我看起来是个不错的解决方案。通宵思考这个问题,我还发现了一种替代方法,它不需要定义类似术语的东西。我不确定是否应该将其作为备选答案发布,或者发布在评论或原始问题中?@Oriol Canela Xandri-如果您的方,c,mapping,bit-manipulation,bitwise-operators,C,Mapping,Bit Manipulation,Bitwise Operators,我修改了答案。非常感谢你扩展了你的答案!我看起来是个不错的解决方案。通宵思考这个问题,我还发现了一种替代方法,它不需要定义类似术语的东西。我不确定是否应该将其作为备选答案发布,或者发布在评论或原始问题中?@Oriol Canela Xandri-如果您的方法也解决了问题,那么您不应该将其隐藏在评论中(代码格式有限),但是不要犹豫,把它作为一个答案贴出来。非常感谢你的答案,并花时间写下来。这听起来是一个很好的起点。我当然可以使用算术运算,但我担心它们可能更容易污染(正如您已经指出的)相邻位。无论如
我修改了答案。非常感谢你扩展了你的答案!我看起来是个不错的解决方案。通宵思考这个问题,我还发现了一种替代方法,它不需要定义类似术语的东西。我不确定是否应该将其作为备选答案发布,或者发布在评论或原始问题中?@Oriol Canela Xandri-如果您的方法也解决了问题,那么您不应该将其隐藏在评论中(代码格式有限),但是不要犹豫,把它作为一个答案贴出来。非常感谢你的答案,并花时间写下来。这听起来是一个很好的起点。我当然可以使用算术运算,但我担心它们可能更容易污染(正如您已经指出的)相邻位。无论如何,我认为你的回答可以为我指明解决这个问题的正确方向。除非有人给出更好的答案,否则我会将其标记为已被接受的答案。只是更新一下,你的答案启发我找到了一个通用的解决方案。我把它贴在这里作为答案。我会让你知道的,以防你感兴趣。谢谢你的帮助。
0 -> 2
1 -> 1
2 -> 1
0, 1, 2, 1, 2, 0, ... //Original array of keys
00 01 10 01 10 00 ... //2-bit pairs representation of keys in a 32bit int
10 01 01 01 01 10 ... //2-bit pairs transformed using the given rule.
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int i;
unsigned int keys[16];
unsigned int bitKeys = 0;
unsigned int mapping[3];
unsigned int result[16];
unsigned int bitResults = 0;
//Initialize random keys and mapping dict
for(i = 0; i<16; i++)
keys[i] = rand() % 3;
bitKeys |= keys[i] << (2*i);
for(i = 0; i<3; i++)
mapping[i] = rand() % 3;
//Get results without using bitwise opperations.
for(i = 0; i<16; i++)
result[i] = mapping[ keys[i] ];
bitResults |= result[i] << (2*i);
//Would it be possible to get bitResults directly from bitKeys efficiently by using bitwise operations?
return 0;
}
BA QP
00 10
01 01
10 01
11 XX
Q = ¬A·¬B
P = A + B
uint32_t keys = 2<<30|0<<10|1<<8|2<<6|1<<4|2<<2|0; // for example
uint32_t vals = ~keys & ~keys<<1 & 0xAAAAAAAA // value_high is !key_high & !key_low
| (keys>>1 | keys) & 0x55555555; // value_low is key_high | key_low
0 ¬A·¬B A ¬B B ¬A A+B 1
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
int main()
{
int i;
unsigned mapping[3];
// generate example mapping
for (i = 0; i < 3; ++i) mapping[i] = rand() % 3, printf(" %d->%d", i, mapping[i]);
puts("");
// determine the mapping expression index 0..7 for high and low value bit
short h = mapping[0]/2 | mapping[1]/2<<1 | mapping[2]/2<<2;
short l = mapping[0]%2 | mapping[1]%2<<1 | mapping[2]%2<<2;
uint32_t keys = 0x1245689A; // for example
uint32_t b = keys, a = keys<<1;
uint32_t term[8] = { 0, ~a&~b, a, ~b, b, ~a, a|b, -1 }; // all possible terms
uint32_t vals = term[h] & 0xAAAAAAAA // value_high
| term[l]>>1 & 0x55555555; // value_low
printf("%8x\n%8x\n", keys, vals);
}
0 -> 2
1 -> 1
2 -> 1
0 -> 0
1 -> 3
2 -> 3
uint32_t keys = /*...*/;
uint32_t values = (((keys & 0xAAAAAAAAu) >> 1) | ((keys & 0x55555555u) << 1))
^ 0xAAAAAAAAu;
uint32_t keys = /*...*/;
uint32_t values = 0xAAAAAAAAu
- (((keys & 0xAAAAAAAAu) >> 1) | (keys & 0x55555555u));
#include <stdio.h>
#include <stdlib.h>
void printBits(size_t const size, void const * const ptr)
{
unsigned char *b = (unsigned char*) ptr;
unsigned char byte;
int i, j;
for (i=size-1;i>=0;i--)
{
for (j=7;j>=0;j--)
{
byte = (b[i] >> j) & 1;
printf("%u", byte);
if(j%2 == 0) printf("|");
}
}
puts("");
}
int test2BitMapping(unsigned int * mapping)
{
int i;
unsigned int keys[16];
unsigned int bitKeys = 0;
unsigned int b = 0;
unsigned int c = 0;
unsigned int d = 0;
unsigned int expand[4] = {0x00000000u, 0x55555555u, 0xAAAAAAAAu, 0xFFFFFFFFu};
unsigned int v12 = 0;
unsigned int v0mask = 0;
unsigned int result[16];
unsigned int bitResults = 0;
unsigned int bitResultsTest = 0;
//Create mapping masks
b = ((1 & mapping[1]) | (2 & mapping[2]));
c = (2 & mapping[1]) | (1 & mapping[2]);
d = mapping[0];
b = expand[b];
c = expand[c];
d = expand[d];
//Initialize random keys
for(i = 0; i<16; i++) {
if(0) { //Test random keys
keys[i] = rand() % 3;
}
else { //Check all keys are generated
keys[i] = i % 3;
}
bitKeys |= keys[i] << (2*i);
}
//Get results without using bitwise opperations.
for(i = 0; i<16; i++) {
result[i] = mapping[ keys[i] ];
bitResultsTest |= result[i] << (2*i);
}
//Get results by using bitwise opperations.
v12 = ( bitKeys & b ) | ( (~bitKeys) & c );
v0mask = bitKeys | (((bitKeys & 0xAAAAAAAAu) >> 1) | ((bitKeys & 0x55555555u) << 1));
bitResults = ( d & (~v0mask) ) | ( v12 & v0mask );
//Check results
if(0) {
for(i = 0; i<3; i++) {
printf("%d -> %d, ", i, mapping[i]);
}
printf("\n");
printBits(sizeof(unsigned int), &bitKeys);
printBits(sizeof(unsigned int), &bitResults);
printBits(sizeof(unsigned int), &bitResultsTest);
printf("-------\n");
}
if(bitResults != bitResultsTest) {
printf("*********\nDifferent\n*********\n");
}
else {
printf("OK\n");
}
}
int main(void)
{
int i, j, k;
unsigned int mapping[3];
//Test using random mapping
for(k = 0; k < 1000; k++) {
for(i = 0; i<3; i++) {
mapping[i] = rand() % 3;
}
test2BitMapping(mapping);
}
//Test all possible mappings
for(i = 0; i<3; i++) {
for(j = 0; j<3; j++) {
for(k = 0; k<3; k++) {
mapping[0] = i;
mapping[1] = j;
mapping[2] = k;
test2BitMapping(mapping);
}
}
}
return 0;
}