Rotazione di bit [C]

di il
5 risposte

Rotazione di bit [C]

Ciao a tutti!
Mi trovo alle prese con un esercizio che chiede di estrarre i bit da una variabile char, stamparli a video e ruotarli di un certo numero di bit verso destra o verso sinistra. La function in base al numero di bit scelto e alla direzione,effettua due shift della char,ognuno dei quali assegnato a una variabile diversa, per poi effettuare un or inclusivo(bit a bit) tra le due variabili e copiare il risultato in un array di char.
Il programma gira correttamente e fornisce il risultato giusto, tranne nel caso in cui nella prima posizione dell'array (ovvero del bit più significativo) dovesse trovarsi '1'; in questo caso la stampa dell'array risulta essere questa: '0000 0000'.

Grazie.

5 Risposte

  • Re: Rotazione di bit [C]

    Ciao ultrasound91,grazie per la risposta, ecco il codice:
    --- Main ---
    
    #include <stdio.h>
    #include <stdlib.h>
    char rotat(char,short);
    void stamp_bin(int);
    
    void main()
    { short n_bit; char ch;
        printf("Inserisci carattere da ruotare:");
        scanf("%c",&ch);
        fflush(stdin);
        stamp_bin(ch);
        printf("\n Di quanti bit ruotare e in che direzione? \n(es.:5 ruota a dx di 5 bit,-5 ruota a sx di 5 bit)\n");
        scanf("%d",&n_bit);
        fflush(stdin);
        if (n_bit>0)
        {
            printf("\n la char e' stata ruotata a destra di %d bit:",n_bit);
            stamp_bin(rotat(ch,n_bit));
        }
        else
        {
            printf("\n la char e' stata ruotata a sinistra di %d bit:",abs(n_bit));
            stamp_bin(rotat(ch,n_bit));
        }
        system("PAUSE");
    }
    
    
    --- Rotat.c ---
    
    #include <stdio.h>
    #include <stdlib.h>
    char rotat(char ch,short n_bit)
    
    { char a,b,c,d,x;
    
        d=abs(n_bit);
    
        if(n_bit>0)
        {
            a=ch>>d;
            b=ch<<8-d;
            c=a|b;
        }
        else
        {
            a=ch>>8-d;
            b=ch<<d;
            c=a|b;
        }
      return c;
    }
    
    
    --- stamp_bin.c ---
    
    #include <stdio.h>
    #include <stdlib.h>
    void stamp_bin(char ch)
    
    { short i,j,z,quoziente,resto; char bit[8];
    
    for(i=0;i<8;i++)
        bit[i]=0;
    
    quoziente=ch;
    resto=ch;
    
    do{     resto=quoziente%2;
            quoziente=quoziente/2;
            bit[i-1]=resto;
            i--;}while(quoziente>=0 && i>=0);
        printf("\nValore in bit: ");
        for(j=0;j<8;j++)
        {
            printf("%d",bit[j]);
        }
    }
  • Re: Rotazione di bit [C]

    Ma perche' non utilizzi le funzioni di manipolazione dei bit del C?

    x << y: shift a sinistra
    x >> y: shift a destra
    x >>> y: shift a destra aritmetici

    ~a: inverte tutti i bit. Quelli a 0 diventano 1, quelli a 1 diventano 0
    a & 0x04: estrae il 3^ bit
    a | 0x04: imposta a 1 il 3 bit
    a & ~0x04: imposta a 0 il 3 bit
    a ^ 0x04: toggle del 3 bit

    Per esempio, per imlementare la rotazione verso sinistra di x di n positioni, per un numero di N bits:

    (x << n) | (x >> (N-n))


    Ma si possono fare cose ancora piu' folli: ad esempio contare il numero di bit a 1, senza ciclare:

    int NumberOfSetBits(uint32_t i)
    {
    i = i - ((i >> 1) & 0x55555555);
    i = (i & 0x33333333) + ((i >> 2) & 0x33333333);
    return (((i + (i >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24;
    }

    Usare 1 byte (8bit) per manipolare un solo bit e' uno spreco di risorse e di tempo

    La parola d'ordine deve essere:

    avere il doppio delle funzionalita' con la meta' del codice

  • Re: Rotazione di bit [C]

    Infatti: ma si puo' fare il lavoro in modo grezzo/rozzo/dozzinale, oppure in modo intelligente!
  • Re: Rotazione di bit [C]

    Grazie a tutti per gli aiuti.
    Sì l'esercizio è a fine didattico per questo sono un po' limitato negli strumenti a disposizione, ed è centrato sull'utilizzo degli operatori bit a bit che uso in rotat.c .
    Per il problema della stampa è come dice ultrasound91, ci sono alcuni parametri di quel particolare caso, che fa leggere il valore della variabile in complemento a 2.
    Comunque sia, ho risolto con la function union e la stampa risulta corretta in ogni caso:
    
    union a{short s[2];
            char c[4];}b;
    b.c[0]=ch;
    
    quoziente=b.s[0];
    resto=b.s[0];
    
    do{     resto=quoziente%2;
            quoziente=quoziente/2;
            bit[i-1]=resto;
            i--;}while(quoziente>=0 && i>=0);
    


    Grazie a tutti!
  • Re: Rotazione di bit [C]

    migliorabile ha scritto:


    Ma perche' non utilizzi le funzioni di manipolazione dei bit del C?

    x << y: shift a sinistra
    x >> y: shift a destra
    x >>> y: shift a destra aritmetici

    ~a: inverte tutti i bit. Quelli a 0 diventano 1, quelli a 1 diventano 0
    a & 0x04: estrae il 3^ bit
    a | 0x04: imposta a 1 il 3 bit
    a & ~0x04: imposta a 0 il 3 bit
    a ^ 0x04: toggle del 3 bit

    Per esempio, per imlementare la rotazione verso sinistra di x di n positioni, per un numero di N bits:

    (x << n) | (x >> (N-n))


    Ma si possono fare cose ancora piu' folli: ad esempio contare il numero di bit a 1, senza ciclare:

    int NumberOfSetBits(uint32_t i)
    {
    i = i - ((i >> 1) & 0x55555555);
    i = (i & 0x33333333) + ((i >> 2) & 0x33333333);
    return (((i + (i >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24;
    }

    Usare 1 byte (8bit) per manipolare un solo bit e' uno spreco di risorse e di tempo

    La parola d'ordine deve essere:

    avere il doppio delle funzionalita' con la meta' del codice

    Certo che si può imparare più da te che in una giornata universitaria!
Devi accedere o registrarti per scrivere nel forum
5 risposte