如何将列数据转换为行数据?
How do I transform column data into row data?
对不起,我想不出一个好的标题。我有一个 8 字节的向量。向量的每个元素都是我正在使用的 8x8 led 矩阵的列数据。因此,如果向量的第一个元素是“11110000”,则意味着该列的前 4 个 LED 亮起,其余的熄灭。我需要将这个“列数据”转换为“行数据”。我会用一个例子告诉你我的意思:
0 1 0 1
1 0 0 1
0 0 1 1
1 1 1 1
= = = =
v1[0] v1[1] v1[2] v1[3]
为简单起见,我将在此示例中使用半字节(实际向量是字节向量)。 v1[0] 是第一列 .. v[3] 是最后一列。对于 v1[0] = "0101",MSB 位于矩阵的顶部,LSB 位于底部(这就是我的 8x8 LED 矩阵的组织方式)。现在,我必须采用另一个向量,并从第一个向量收集行,因此“行向量”将如下所示:
v2[0] = 0101
v2[1] = 1001
v2[2] = 0011
v2[3] = 1111
这是我目前尝试过的方法:
unsigned char vector[8] = {15, 15, 15, 15, 15, 15, 15, 15};
unsigned char x = 0;
unsigned char mask = 128;
for (int i = 0; i < 8; i++)
{
printf("%i ", vector[i]);
}
printf("\n");
for (int i = 0; i < 8; i++)
{
x = 0;
for (int j = 0; j < 8; j++)
{
x |= vector[j] & mask;
x >>= 1;
}
mask >>= 1;
printf("%i ", x);
}
printf("\n");
所以我的列向量全是 15,所以是“00001111”。行向量的前 4 个元素应为“00000000”,后 4 个元素应为“11111111”。我的代码不使用向量作为行,为了简单起见,我只是制作“行”,然后打印它。这段代码背后的想法是使用掩码 = 128 ("10000000"),并遍历列向量,并取每个元素的第一位。当我从一个元素中取一点时,我将行变量“x”向右移动,以便为下一位腾出空间。在完成一行之后,我将掩码向右移动,以从列中取出第二位。此代码应打印:
15 15 15 15 15 15 15 15
0 0 0 0 255 255 255 255
但它打印:
15 15 15 15 15 15 15 15
0 0 0 0 7 3 1 0
代码有什么问题?
编辑:让我再举一个例子。如果我的列向量满了255,那么每个元素都是“11111111”,那就意味着我的行向量也应该满了255。我的代码不是这样的:
255 255 255 255 255 255 255 255
255 255 255 255 255 255 255 255
输出这个:
255 255 255 255 255 255 255 255
127 63 31 15 7 3 1 0
让我们仔细看看内部循环:
for (int j = 0; j < 8; j++)
{
x |= vector[j] & mask;
x >>= 1;
}
在此循环中,您需要为 x
.
的每个位位置生成一个值
第一次通过此循环 mask
是 128,因此它从向量中的每个字节中获取高位,将其放入 x
中的高位,然后右移.当你退出这个循环时,你移动了太多次,所以你最终得到一个空的高位。
下一次通过这个循环mask
是64,所以它分离出第二位(从左边开始)放在x
中的第二位,然后右移。请注意,现在 x
的高位永远不会被设置。同样的情况发生在外循环的后续迭代中,x
中的更多位没有被触及。
获得隔离位后,您需要做的是将其移至正确位置,然后再将其放入 x
。这可以通过首先对孤立位应用 !
运算符两次以将其标准化为 1 或 0,然后根据 j
:
的当前值将其左移来完成
for (int j = 0; j < 8; j++)
{
x |= !!(vector[j] & mask) << (7 - j);
}
以下建议代码:
- 干净地编译
- 执行所需的功能
现在,建议的代码:
#include <stdio.h>
int main( void )
{
unsigned char vector[8] = {15, 15, 15, 15, 15, 15, 15, 15};
for( size_t column = 0; column < 8; column++ )
{
for( size_t row = 0; row < 8; row++ )
{
printf( "%c", ((vector[ row ] >> (7-column)) & 0x01) | 0x30 );
}
printf( "\n" );
}
}
典型的 运行 代码结果为:
00000000
00000000
00000000
00000000
11111111
11111111
11111111
11111111
对不起,我想不出一个好的标题。我有一个 8 字节的向量。向量的每个元素都是我正在使用的 8x8 led 矩阵的列数据。因此,如果向量的第一个元素是“11110000”,则意味着该列的前 4 个 LED 亮起,其余的熄灭。我需要将这个“列数据”转换为“行数据”。我会用一个例子告诉你我的意思:
0 1 0 1
1 0 0 1
0 0 1 1
1 1 1 1
= = = =
v1[0] v1[1] v1[2] v1[3]
为简单起见,我将在此示例中使用半字节(实际向量是字节向量)。 v1[0] 是第一列 .. v[3] 是最后一列。对于 v1[0] = "0101",MSB 位于矩阵的顶部,LSB 位于底部(这就是我的 8x8 LED 矩阵的组织方式)。现在,我必须采用另一个向量,并从第一个向量收集行,因此“行向量”将如下所示:
v2[0] = 0101
v2[1] = 1001
v2[2] = 0011
v2[3] = 1111
这是我目前尝试过的方法:
unsigned char vector[8] = {15, 15, 15, 15, 15, 15, 15, 15};
unsigned char x = 0;
unsigned char mask = 128;
for (int i = 0; i < 8; i++)
{
printf("%i ", vector[i]);
}
printf("\n");
for (int i = 0; i < 8; i++)
{
x = 0;
for (int j = 0; j < 8; j++)
{
x |= vector[j] & mask;
x >>= 1;
}
mask >>= 1;
printf("%i ", x);
}
printf("\n");
所以我的列向量全是 15,所以是“00001111”。行向量的前 4 个元素应为“00000000”,后 4 个元素应为“11111111”。我的代码不使用向量作为行,为了简单起见,我只是制作“行”,然后打印它。这段代码背后的想法是使用掩码 = 128 ("10000000"),并遍历列向量,并取每个元素的第一位。当我从一个元素中取一点时,我将行变量“x”向右移动,以便为下一位腾出空间。在完成一行之后,我将掩码向右移动,以从列中取出第二位。此代码应打印:
15 15 15 15 15 15 15 15
0 0 0 0 255 255 255 255
但它打印:
15 15 15 15 15 15 15 15
0 0 0 0 7 3 1 0
代码有什么问题?
编辑:让我再举一个例子。如果我的列向量满了255,那么每个元素都是“11111111”,那就意味着我的行向量也应该满了255。我的代码不是这样的:
255 255 255 255 255 255 255 255
255 255 255 255 255 255 255 255
输出这个:
255 255 255 255 255 255 255 255
127 63 31 15 7 3 1 0
让我们仔细看看内部循环:
for (int j = 0; j < 8; j++)
{
x |= vector[j] & mask;
x >>= 1;
}
在此循环中,您需要为 x
.
第一次通过此循环 mask
是 128,因此它从向量中的每个字节中获取高位,将其放入 x
中的高位,然后右移.当你退出这个循环时,你移动了太多次,所以你最终得到一个空的高位。
下一次通过这个循环mask
是64,所以它分离出第二位(从左边开始)放在x
中的第二位,然后右移。请注意,现在 x
的高位永远不会被设置。同样的情况发生在外循环的后续迭代中,x
中的更多位没有被触及。
获得隔离位后,您需要做的是将其移至正确位置,然后再将其放入 x
。这可以通过首先对孤立位应用 !
运算符两次以将其标准化为 1 或 0,然后根据 j
:
for (int j = 0; j < 8; j++)
{
x |= !!(vector[j] & mask) << (7 - j);
}
以下建议代码:
- 干净地编译
- 执行所需的功能
现在,建议的代码:
#include <stdio.h>
int main( void )
{
unsigned char vector[8] = {15, 15, 15, 15, 15, 15, 15, 15};
for( size_t column = 0; column < 8; column++ )
{
for( size_t row = 0; row < 8; row++ )
{
printf( "%c", ((vector[ row ] >> (7-column)) & 0x01) | 0x30 );
}
printf( "\n" );
}
}
典型的 运行 代码结果为:
00000000
00000000
00000000
00000000
11111111
11111111
11111111
11111111