扭转蚕食

因此,我遇到了一个有关“通过逆转其位数来建立新数字”的问题。 练习看起来像这样:写一个给定 无符号n 一种) 退货 值以半字节相反的顺序排列

我当时认为32位无符号的所有8个半字节应该以相反的顺序放置。因此,以数字24为例,即00000000000000000000000000011000。 =>反向应为:10000001000000000000000000000000。

#include <stdio.h>

unsigned getNibble(unsigned n,unsigned p){

unsigned mask = 0xFu;
unsigned nibble = 0;

nibble = (n&(mask<<p))>>p;

return nibble;

}


unsigned swapNibbles(unsigned n){
unsigned new = 0;
unsigned nibble;
for(unsigned i=0;i<(sizeof(n)*8);i=i+4){
    nibble = getNibble(n,i);
    new = (new<<i) + nibble;
}

return new;
}


int main(void) {

printf("0x%x",swapNibbles(24));

return 0;
}

我尝试调试它,直到进行到1点为止,它运行良好。 在向右移动的其中之一处,它将我的“新”变量转换为0。

Linpeipei1985 回答:扭转蚕食

此声明

new = (new << i) + nibble;

是错误的。应该有

new = (new << 4) + nibble;
,

一种可以并行工作的方法:

uint32_t n = ...;

// Swap the nibbles of each byte.
n = (n & 0x0F0F0F0F ) << 4
  | (n & 0xF0F0F0F0 ) >> 4;

// Swap the bytes of each byte pair.
n = ( n & 0x00FF00FF ) << 8
  | ( n & 0xFF00FF00 ) >> 8;

// Swap the byte pairs.
n = ( n & 0x0000FFFF ) << 16
  | ( n & 0xFFFF0000 ) >> 16;

并行执行工作可以大大减少操作次数。

          OP's       This     
          Approach   Approach 
--------  ---------  ---------
Shifts     24 /  48    6 /   8    32 bits / 64 bits
Ands        8 /  16    6 /   8
Ors*        8 /  16    3 /   4
Assigns     8 /  16    3 /   4
Adds        8 /  16    0 /   0
Compares    8 /  16    0 /   0
--------  ---------  ---------
Total      64 / 128   18 /  24
--------  ---------  ---------
Scale     O(N)       O(log(N))

* Addition was used as "or" in your solution.
,
int main (void)
{
    uint32_t x = 0xDEADBEEF;
    printf("original 4 bytes %X\n",x);
    
    uint32_t y = 0;

    for(uint8_t i = 0 ; i < 32 ; i += 4)
    {
        y <<= 4;
        y |= x>>i & 0xF;
    }
    
    printf("reverse order nibbles %X\n",y);

return 0;
}

可以将其设为通用函数,以接受所有8,16,32位数字。但是现在,这可以解决您在代码中面临的错误。

但是我要指出的是,ikegami的代码比这种方法要好得多。

本文链接:https://www.f2er.com/3157425.html

大家都在问