【问题标题】:How do I transform column data into row data?如何将列数据转换为行数据?
【发布时间】:2021-03-27 10:36:50
【问题描述】:

对不起,我只是想不出一个好的标题。我有一个 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 位于 matirx 的顶部,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

【问题讨论】:

    标签: c byte bit bit-shift


    【解决方案1】:

    让我们仔细看看内部循环:

    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);
    }
    

    【讨论】:

    • 您能否再详细解释一下“!!”是什么?有吗?
    • @OrosTom ! 是逻辑否定运算符。如果其操作数为 0,则结​​果为 1,否则结果为 0。因此,通过两次应用,0 保持为零,非零变为 1。
    • 是的,我知道!运算符,但是如何两次“标准化”结果呢?有没有“!!”不应该一样吗?
    • @OrosTom !!0 == !1 == 0!!1 == !0 == 1!!2 == !0 == 1
    【解决方案2】:

    以下建议的代码:

    1. 干净编译
    2. 执行所需的功能

    现在,建议的代码:

    #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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-09-24
      相关资源
      最近更新 更多