找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 6070|回復(fù): 28
打印 上一主題 下一主題
收起左側(cè)

1個(gè)字節(jié)數(shù)據(jù) 怎么把高八位和低八位對(duì)稱換位?

  [復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:1030798 發(fā)表于 2023-4-29 19:14 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
比如1000 0000變成0000 0001
1100 0101變成1010 0011
這樣對(duì)稱換位,大佬們
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:235200 發(fā)表于 2023-4-30 00:31 | 只看該作者
數(shù)據(jù)存dat1,換位結(jié)果存dat2
for (i=0;i<8;i++)
{
   j=(bit)(dat1&0x80);
    if (j)
       dat2=dat2+0x80;
    dat1=dat1<<1;
    dat2=dat>>1;
}
回復(fù)

使用道具 舉報(bào)

板凳
ID:1074756 發(fā)表于 2023-4-30 09:10 來(lái)自觸屏版 | 只看該作者
在C語(yǔ)言中,可以使用位運(yùn)算符對(duì)二進(jìn)制數(shù)進(jìn)行位反轉(zhuǎn)操作。  對(duì)于將二進(jìn)制數(shù)1100 0101變成1010 0011,可以這么實(shí)現(xiàn):  c unsigned char x = 0xC5; // 將16進(jìn)制數(shù)0xC5賦值給無(wú)符號(hào)字符變量x x = ((x & 0x55) << 1) | ((x & 0xAA) >> 1); // 與0x55做與操作得到奇數(shù)位,與0xAA做與操作得到偶數(shù)位,然后將奇偶位的結(jié)果進(jìn)行交換 x = ((x & 0x33) << 2) | ((x & 0xCC) >> 2); // 與0x33做與操作得到8位中的4位一組的左側(cè)4位,與0xCC做與操作得到右側(cè)4位,然后將每組4位的位置互換 x = ((x & 0x0F) << 4) | ((x & 0xF0) >> 4); // 與0x0F做與操作得到低4位,與0xF0做與操作得到高4位,然后將低高位的結(jié)果進(jìn)行交換 最終得到的x的值為十六進(jìn)制數(shù)0xA3,即二進(jìn)制數(shù)1010 0011
回復(fù)

使用道具 舉報(bào)

地板
ID:1030798 發(fā)表于 2023-4-30 09:26 來(lái)自觸屏版 | 只看該作者
csmyldl 發(fā)表于 2023-4-30 00:31
數(shù)據(jù)存dat1,換位結(jié)果存dat2
for (i=0;i

大佬我能說沒看懂嗎
回復(fù)

使用道具 舉報(bào)

5#
ID:883242 發(fā)表于 2023-4-30 09:47 | 只看該作者
召喚獸 發(fā)表于 2023-4-30 09:10
在C語(yǔ)言中,可以使用位運(yùn)算符對(duì)二進(jìn)制數(shù)進(jìn)行位反轉(zhuǎn)操作。  對(duì)于將二進(jìn)制數(shù)1100 0101變成1010 0011,可以這 ...

是的,hacker's delight這本書第7章說的就是這種蝶形算法。
回復(fù)

使用道具 舉報(bào)

6#
ID:420836 發(fā)表于 2023-4-30 09:49 | 只看該作者
要將高位位置與低位位置交換,您可以使用以下代碼并獲得二進(jìn)制格式。
char new_byte;
bool new_bit[8];
char byte1;
bool bit[8];
for(int i= 0; i<8; i++)
{
        bit[i] = ((byte1>>i) & 0x01);
        new_bit[7-i] = bit[i];
}
如果要獲取新字節(jié),請(qǐng)使用以下代碼:
unsigned int bitsToBytes(unsigned char *bits)
{
  unsigned int sum = 0;
  for (int i = 0; i < 8; i++)
  {
    sum += bits[i] - '0';
    sum<<=1;
  }
  return sum;

}

new_byte = bitToByte(*new_bit);
回復(fù)

使用道具 舉報(bào)

7#
ID:277550 發(fā)表于 2023-4-30 10:37 | 只看該作者
這樣


#include<stdio.h>

int main(int argc, char*argv[]){
        unsigned char a=0xab, b;
       
        printf("%02x\r\n", a);

        b = (a>>4)&0xf;
        a = (a<<4) | b;         //這2行

        printf("%02x\r\n", a);

        return 0;
}
回復(fù)

使用道具 舉報(bào)

8#
ID:277550 發(fā)表于 2023-4-30 10:58 | 只看該作者
上一帖確實(shí)看錯(cuò),不管管理員確認(rèn)了,直接補(bǔ)一樓


#include<stdio.h>

void printBin(unsigned char a){
        int i;
        for(i=0; i<8; i++){
                printf("%d", a&0x80?1:0);
                a=a<<1;
        }
}

int main(int argc, char*argv[]){
        unsigned char a=0xab, b, i, j;
        for(i=0x79; i<0x8f; i++){//測(cè)試幾個(gè)數(shù),看結(jié)果是否對(duì)
                a=i;
                printBin(a);
                printf(" ");
        }
        printf("\r\n");
       
        for(i=0x79; i<0x8f; i++){
                a=i;
               
                //對(duì)稱調(diào)換---begin
                b=0;
                for(j=0; j<8; j++){
                        b=b | ((a&1)<<(7-j)) ;
                        a=a>>1;
                }                                       
                //對(duì)稱調(diào)換---end
                printBin(b);
                printf(" ");
        }
        printf("\r\n\r\n");
       
       
        //=================================
        a=0xab;
        printf("%02x\r\n", a);
        b=(a>>4) | (a<<4);  //高低對(duì)調(diào)
        printf("%02x\r\n", b);
       
        return 0;
}


// http://www.torrancerestoration.com/bbs/dpj-228623-1.html
//VC2008測(cè)試過。
回復(fù)

使用道具 舉報(bào)

9#
ID:291668 發(fā)表于 2023-4-30 11:02 | 只看該作者
先做高低字節(jié)交換,再按位取反。
回復(fù)

使用道具 舉報(bào)

10#
ID:1034262 發(fā)表于 2023-4-30 11:45 | 只看該作者
查表最快
回復(fù)

使用道具 舉報(bào)

11#
ID:491577 發(fā)表于 2023-4-30 13:19 | 只看該作者
用二樓的程序簡(jiǎn)化一下:
數(shù)據(jù)存dat1,換位結(jié)果存dat2
dat2=0; //開始要先清零
for (i=0;i<8;i++)
{
    if (dat1&0x80)  //判斷dat1最高位是否=1
    dat2=dat2+1;  //如果dat1最高位=1,將dat2最低位+1,相當(dāng)于將dat1高位移到dat2低位。
    dat1=dat1<<1;
    dat2=dat2<<1;
}
回復(fù)

使用道具 舉報(bào)

12#
ID:163285 發(fā)表于 2023-4-30 15:25 | 只看該作者
分別提取各位,然后用堆棧。
回復(fù)

使用道具 舉報(bào)

13#
ID:57657 發(fā)表于 2023-4-30 16:41 | 只看該作者
查表浪費(fèi)內(nèi)存空間,循環(huán)語(yǔ)句浪費(fèi)時(shí)間,還是Verilog劃算:
  1. module main(                                //對(duì)稱換位模塊
  2.         input [7:0] in,                //[8位寬]輸入
  3.         output [7:0] out                //[8位寬]輸出

  4. );
  5. genvar i;
  6. generate
  7. for(i=0;i<8;i=i+1) begin:gen
  8.         assign out[i] = in[7-i];
  9. end
  10. endgenerate
  11. endmodule
復(fù)制代碼
回復(fù)

使用道具 舉報(bào)

14#
ID:213173 發(fā)表于 2023-4-30 16:48 | 只看該作者
寫一個(gè)簡(jiǎn)單函數(shù),容易理解些。
unsigned char Conversion(unsigned char dat)
{
        unsigned char i,temp;
        for(i=0;i<8;i++)
        {
                temp|=((dat&0x01)<<(7-i));
                dat>>=1;
        }
        return temp;
}
回復(fù)

使用道具 舉報(bào)

15#
ID:688692 發(fā)表于 2023-4-30 22:23 | 只看該作者
老問題了,論壇有討論過這個(gè),8位查表速度最快,移位蝶形也不見得省程序空間(可以自己對(duì)比一下編譯出來(lái)的code空間和跑完函數(shù)花的機(jī)器周期state),4位查表綜合代碼長(zhǎng)度和執(zhí)行速度折中最好。
回復(fù)

使用道具 舉報(bào)

16#
ID:73992 發(fā)表于 2023-4-30 23:39 | 只看該作者
將值存入位尋址區(qū),然后cy取位。acc移位。以 51為例
mov 20h,#00110110b  //假設(shè)值為00110110b
mov cy,07h   //20h最高位
RR a        //ACC右移
mov cy,06h   //20h次高位
RR a        //ACC右移
.......      ..........
八次過后,結(jié)果存在acc中。 嵌入到C語(yǔ)言中
回復(fù)

使用道具 舉報(bào)

17#
ID:491577 發(fā)表于 2023-5-1 01:14 | 只看該作者
npn 發(fā)表于 2023-4-30 16:41
查表浪費(fèi)內(nèi)存空間,循環(huán)語(yǔ)句浪費(fèi)時(shí)間,還是Verilog劃算:

Verilog還沒有了解過,要認(rèn)真學(xué)習(xí)一下。不過下面的語(yǔ)句好像也是循環(huán):
for(i=0;i<8;i=i+1) begin:gen
        assign out = in[7-i];
回復(fù)

使用道具 舉報(bào)

18#
ID:57657 發(fā)表于 2023-5-1 08:15 | 只看該作者
hhh402 發(fā)表于 2023-5-1 01:14
Verilog還沒有了解過,要認(rèn)真學(xué)習(xí)一下。不過下面的語(yǔ)句好像也是循環(huán):
for(i=0;i

Verilog是一種并行語(yǔ)言,與串行語(yǔ)言不同,這里的循環(huán)是將8根導(dǎo)線接上。
回復(fù)

使用道具 舉報(bào)

19#
ID:989772 發(fā)表于 2023-5-1 08:31 | 只看該作者
   int dat1 = 0xc5;
   int dat2 = 0;
   for(int l=0, d4 =128; l<8; l++ )
   {   
           dat2 += dat1%2*d4;
           dat1/=2;
           d4/=2;          
   }
回復(fù)

使用道具 舉報(bào)

20#
ID:1030798 發(fā)表于 2023-5-2 13:46 | 只看該作者
wulin 發(fā)表于 2023-4-30 16:48
寫一個(gè)簡(jiǎn)單函數(shù),容易理解些。
unsigned char Conversion(unsigned char dat)
{

如果是0xAA他就不行呀
回復(fù)

使用道具 舉報(bào)

21#
ID:883242 發(fā)表于 2023-5-2 15:02 | 只看該作者
cnos 發(fā)表于 2023-4-30 22:23
老問題了,論壇有討論過這個(gè),8位查表速度最快,移位蝶形也不見得省程序空間(可以自己對(duì)比一下編譯出來(lái)的c ...

蝶形算法在32位機(jī)對(duì)換32位數(shù)據(jù)的高低位還是很有性價(jià)比的,樓主連自己的單片機(jī)型號(hào)什么的都不說,誰(shuí)也沒法猜出最佳方案,大家散了吧。
回復(fù)

使用道具 舉報(bào)

22#
ID:213173 發(fā)表于 2023-5-2 15:14 | 只看該作者
231244234 發(fā)表于 2023-5-2 13:46
如果是0xAA他就不行呀

0xAA轉(zhuǎn)換后0x55,你沒有驗(yàn)證怎么說不行?
回復(fù)

使用道具 舉報(bào)

23#
ID:1073399 發(fā)表于 2023-5-2 23:02 | 只看該作者
  1. unsigned char swapBits(unsigned char data)
  2. {
  3.   return ((data >> 4) & 0x0F) | ((data << 4) & 0xF0);
  4. }
復(fù)制代碼
這里使用了右移和左移操作來(lái)將高八位和低八互換位置。首先將數(shù)據(jù)向高四清,只低四位的數(shù)據(jù)。然后再將數(shù)據(jù)向左移動(dòng)4位(低四位移到高四位),與0xF0進(jìn)行按位與運(yùn)算,將低四位清零,只留下高四位的數(shù)據(jù)。最后將這兩位或運(yùn)算合并起來(lái),就完成了高八位和對(duì)稱互換位置的操作。
回復(fù)

使用道具 舉報(bào)

24#
ID:491577 發(fā)表于 2023-5-2 23:41 | 只看該作者
23樓的轉(zhuǎn)換錯(cuò)了吧,樓主意思是ABCDEFG變成GFEDCBA。不是高四位與低四位互換。
回復(fù)

使用道具 舉報(bào)

25#
ID:401564 發(fā)表于 2023-5-3 19:59 | 只看該作者
什么代碼簡(jiǎn)單,容易理解,就用這個(gè)代碼,什么占內(nèi)存,速度快的.壓根就不需要考慮
我公司之前用的是512B內(nèi)存的單片機(jī),隨便寫點(diǎn)代碼就用完了
我也曾經(jīng)想過所謂的"優(yōu)化代碼"
折騰了好久,才發(fā)現(xiàn),1K內(nèi)存單片機(jī)的價(jià)格僅僅高了一分錢而已
得多少量才把這1分錢省回來(lái)呀,干脆就不折騰了,直接換1K的
回復(fù)

使用道具 舉報(bào)

26#
ID:77589 發(fā)表于 2023-5-4 11:57 | 只看該作者
Y_G_G 發(fā)表于 2023-5-3 19:59
什么代碼簡(jiǎn)單,容易理解,就用這個(gè)代碼,什么占內(nèi)存,速度快的.壓根就不需要考慮
我公司之前用的是512B內(nèi)存的 ...

有道理。。。。。。。!
回復(fù)

使用道具 舉報(bào)

27#
ID:1073939 發(fā)表于 2023-5-4 15:30 | 只看該作者
wulin 發(fā)表于 2023-4-30 16:48
寫一個(gè)簡(jiǎn)單函數(shù),容易理解些。
unsigned char Conversion(unsigned char dat)
{

你的代碼改成這樣,效率更高。
  1. unsigned char Conversion(unsigned char dat)
  2. {
  3.     unsigned char i, r = 0;
  4.     for (i = 0; i < 8; i++)
  5.     {
  6.         r <<= 1;
  7.         r += dat & 0x01;
  8.         dat >>= 1;
  9.     }
  10.     return r;
  11. }
復(fù)制代碼
回復(fù)

使用道具 舉報(bào)

28#
ID:1074495 發(fā)表于 2023-5-4 15:48 | 只看該作者
用匯編的話,直接選擇帶進(jìn)位的左右循環(huán),CY標(biāo)志位做中轉(zhuǎn)站就可以

      
回復(fù)

使用道具 舉報(bào)

29#
ID:824490 發(fā)表于 2023-5-5 11:36 | 只看該作者
召喚獸 發(fā)表于 2023-4-30 09:10
在C語(yǔ)言中,可以使用位運(yùn)算符對(duì)二進(jìn)制數(shù)進(jìn)行位反轉(zhuǎn)操作。  對(duì)于將二進(jìn)制數(shù)1100 0101變成1010 0011,可以這 ...

好一只漂亮、輕靈的蝴蝶!
學(xué)習(xí)了~~
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表