Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

[C] proste odwracanie bitów

explosive 24 Maj 2010 13:53 5192 9
  • #1 24 Maj 2010 13:53
    explosive
    Poziom 9  

    Muszę odwrócić kolejność bitów, przykładowo:
    11111110 -> 01111111
    11111000 -> 00011111

    dane mam w zmiennej char.
    (chodzi o wysyłanie znaków na LCD, odwrotnie połączyłem PORT z LCD ;/ ).

    0 9
  • Pomocny post
    #2 24 Maj 2010 15:15
    Dr.Vee
    VIP Zasłużony dla elektroda

    Najszybciej tablicą z 256 wpisami po jednym bajcie, albo dwa razy skorzystaj z tabeli z 16 wpisami:

    Code:
    uint8_t byteSwap(uint8_t x)
    
    {
        const uint8_t lower = x & 0x0f;
        const uint8_t upper = x >> 4;
        return (nibbleSwap(lower) << 4) | nibbleSwap(upper);
    }

    uint8_t nibbleSwap(uint8_t x)
    {
        const uint8_t swap4bits[16] = {...};
        return swap4bits[x & 0xf];
    }

    Pozdrawiam,
    Dr.Vee

    0
  • Pomocny post
    #3 24 Maj 2010 16:40
    beluosus
    Poziom 25  

    Code:
    unsigned char reverseByte(unsigned char c)
    
    {
        int i;
        unsigned char d = 0;
        for (i = 0; i < 8; i++)
        {
            d <<= 1;
            d |= c & 1;
            c >>= 1;
        }

        return d;
    }

    0
  • Pomocny post
    #4 24 Maj 2010 19:52
    Xitami
    Poziom 29  

    Code:
    const unsigned char XLAT[256]={
    
      0,128, 64,192, 32,160, 96,224, 16,144, 80,208, 48,176,112,240,
      8,136, 72,200, 40,168,104,232, 24,152, 88,216, 56,184,120,248,
      4,132, 68,196, 36,164,100,228, 20,148, 84,212, 52,180,116,244,
     12,140, 76,204, 44,172,108,236, 28,156, 92,220, 60,188,124,252,
      2,130, 66,194, 34,162, 98,226, 18,146, 82,210, 50,178,114,242,
     10,138, 74,202, 42,170,106,234, 26,154, 90,218, 58,186,122,250,
      6,134, 70,198, 38,166,102,230, 22,150, 86,214, 54,182,118,246,
     14,142, 78,206, 46,174,110,238, 30,158, 94,222, 62,190,126,254,
      1,129, 65,193, 33,161, 97,225, 17,145, 81,209, 49,177,113,241,
      9,137, 73,201, 41,169,105,233, 25,153, 89,217, 57,185,121,249,
      5,133, 69,197, 37,165,101,229, 21,149, 85,213, 53,181,117,245,
     13,141, 77,205, 45,173,109,237, 29,157, 93,221, 61,189,125,253,
      3,131, 67,195, 35,163, 99,227, 19,147, 83,211, 51,179,115,243,
     11,139, 75,203, 43,171,107,235, 27,155, 91,219, 59,187,123,251,
      7,135, 71,199, 39,167,103,231, 23,151, 87,215, 55,183,119,247,
     15,143, 79,207, 47,175,111,239, 31,159, 95,223, 63,191,127,255};
     
    #define reverse(a) (XLAT[a])

    0
  • #6 24 Maj 2010 21:56
    beluosus
    Poziom 25  

    Dżyszla napisał:
    A nie można by zastosować wstawki assemblerowej i skorzystanie z polecenia ROL?

    Jak sobie wyobrażasz zrobić to ROL'em? 8 razy ROL i mamy na wyjściu ten sam bajt co na wejściu (co innego MSB<->LSB, wtedy 4 razy i gotowe).

    Z tablicą to jednak najlepszy sposób (aczkolwiek najpierw trzeba było napisać funkcję podobną do mojej żeby obliczyć wartości do tablicy :P), ulubiony XLAT Xitamiego (czy jak to odmienić). Wyszedł mi ponad 3 razy szybciej w teście.

    Btw, po skopiowaniu niechcący wkleił mi się w google i wyskoczyła jakaś ruska strona, jest tam sposób z tablicą jak i również prawie identyczny kod, który napisałem post wcześniej. :)

    0
  • Pomocny post
    #7 24 Maj 2010 22:15
    Dżyszla
    Poziom 42  

    Sorry, pomyliłem polecenia, to fakt... ale ja bym to zrobił tak (wersja wydajnościowa, bez pętli):

    Code:

    asm
    {
       MOV al,zmienna
       XOR ah,ah
       SHR al,1
       RCL ah,1
       SHR al,1
       RCL ah,1
       SHR al,1
       RCL ah,1
       SHR al,1
       RCL ah,1
       SHR al,1
       RCL ah,1
       SHR al,1
       RCL ah,1
       SHR al,1
       RCL ah,1
       SHR al,1
       RCL ah,1
       MOV zmienna,ah
    }
    Będzie szybsze niż zaprezentowany kod w C (nawet, jeśli zastosujemy pętlę) i mniej pamięciożerne niż tablica.

    0
  • Pomocny post
    #8 25 Maj 2010 01:32
    Xitami
    Poziom 29  

    beluosus napisał:
    ...
    Z tablicą to jednak najlepszy sposób (aczkolwiek najpierw trzeba było napisać funkcję podobną do mojej żeby obliczyć wartości do tablicy
    ...

    Mam coś niepodobnego :D, tu indeksy tablic od jeden, czyli tu i tam powtykałem +/- 1
    Code:
    XL(N)={ local(XLAT,j,Temp,k);
    
       XLAT= vector(N);
       for (i=0, N-1,
          XLAT[i+1]=i);
       j= N\2;
       for (i=1, N-2,
          if(i<j,
             Temp=XLAT[i+1];XLAT[i+1]=XLAT[j+1];XLAT[j+1]=Temp);
          k= N/2;
          while(k<=j,
             j-=k;
             k/=2);
          j+=k
       );
       XLAT
    }

    0
  • #9 25 Maj 2010 10:37
    explosive
    Poziom 9  

    Pierwsza propozycja beluosus'a zadziałała wspaniale, na moje potrzeby to wystarczy. Dzięki bardzo wszystkim za pomoc, wyczerpaliście temat zupełnie ;-)
    Pozdrawiam

    0
  • #10 25 Maj 2010 23:27
    Dr.Vee
    VIP Zasłużony dla elektroda

    Po co wstawki asemblerowe w odpowiedzi na pytanie o algorytm w C?
    Usunąłem posty z dyskusją o algorytmach w asm.
    Temat zamykam.

    0