• 转置位矩阵


    /*
     * http://www-graphics.stanford.edu/~seander/bithacks.html#ReverseByteWith64Bits
     * 
     * 0010 0100 -- 24
     * 0010 0001 -- 21 
     * 1111 0000 -- F0
     * 0111 1111 -- 7F
     * 1000 0000 -- 80
     * 0011 0111 -- 37
     * 1111 1111 -- FF
     * 0001 1111 -- 1F
     * |||| ||||
     * 4CFC 898A
     * 546E CEEE
     * 
     */
    
    uint8_t t1[ 8 ] =
    { 0x24, 0x21, 0xf0, 0x7f, 0x80, 0x37, 0xff, 0x1f };
    
    uint8_t t2[ 8 ];
    
    union
    {
      uint32_t l[ 2 ];
      uint8_t c[ 8 ];
    } Tmp;
    
    void foo( void )
    {
      long Ll, Lh;
      uint8_t i;
      for ( i = 0; i < 8; i++ )
        Tmp.c = t1;
      
      i = 8;
      while ( i-- )
      {
        Ll = ( Tmp.l[ 0 ] & 0x01010101 ) * 0x01020408;  // 0x08040201
        Lh = ( Tmp.l[ 1 ] & 0x01010101 ) * 0x01020408;  // Reserved
          
        t2 = (uint8_t) ( ( ( Lh & 0x0F000000 ) >> 20 )
          | ( ( Ll & 0x0F000000 ) >> 24 ) );
        
        Tmp.l[ 0 ] >>= 1;
        Tmp.l[ 1 ] >>= 1;
      }
    }
    
    // 《高效程序的奥秘》翻译 Henry S. Warren. Jr. 的“Hacher's Delight"
    // 0x57 0x17 0x97 0x13 0x37 0xf6 0x32 0x2a
    void transpose8( uint8_t i[ 8 ], uint8_t o[ 8 ] )
    {
      uint32_t x, y, t;
      
      x = ( i[ 0 ] << 24 ) | ( i[ 1 ] << 16 ) | ( i[ 2 ] << 8 ) | i[ 3 ];
      y = ( i[ 4 ] << 24 ) | ( i[ 5 ] << 16 ) | ( i[ 6 ] << 8 ) | i[ 7 ];
      
      t = ( x & 0xf0f0f0f0 ) | ( ( y >> 4 ) & 0x0f0f0f0f );
      y = ( ( x << 4 ) & 0xf0f0f0f0 ) | ( y & 0x0f0f0f0f );
      x = t;
      
      t = ( x ^ ( x >> 14 ) ) & 0x0000cccc;
      x = x ^ t ^ ( t << 14 );
      t = ( y ^ ( y >> 14 ) ) & 0x0000cccc;
      y = y ^ t ^ ( t << 14 );
      
      t = ( x ^ ( x >> 7 ) ) & 0x00aa00aa;
      x = x ^ t ^ ( t << 7 );
      t = ( y ^ ( y >> 7 ) ) & 0x00aa00aa;
      y = y ^ t ^ ( t << 7 );
      
      o[ 7 ] = x >> 24;
      o[ 6 ] = x >> 16;
      o[ 5 ] = x >> 8;
      o[ 4 ] = x;
      o[ 3 ] = y >> 24;
      o[ 2 ] = y >> 16;
      o[ 1 ] = y >> 8;
      o[ 0 ] = y;
    }
    
    int main( void )
    {
      int i;
      uint8_t t1[ 8 ] =
      { 0x24, 0x21, 0xf0, 0x7f, 0x80, 0x37, 0xff, 0x1f };
      uint8_t t2[ 8 ];
      
      transpose8( t1, t2 );
      for ( i = 0; i < 8; i++ )
        printf( "0x%x ", t2 );
    }
  • 相关阅读:
    旧文备份:CANopen协议PDO的几种传输方式
    CANopen 基础
    单片机FLASH与RAM、ROM的关系
    在CANopen网络中通过LSS服务设置节点地址和网络波特率
    STM32F103 CAN中断发送功能的再次讨论
    由RS-232串口到PROFIBUS-DP总线的转换接口设计
    profibus 的DPV0 和DPV1
    PROFIBUS-DP
    profibus总线和profibus dp的区别
    获取验证码倒计时
  • 原文地址:https://www.cnblogs.com/shangdawei/p/4733233.html
Copyright © 2020-2023  润新知