[C] convertire un numero da little endian a big endian

Pubblicità

ilfe98

Utente Èlite
Messaggi
3,083
Reazioni
1,317
Punteggio
134
Salve a tutti problema odierno:
Creare i file byteswap.h e byteswap.c che consentano di utilizzare la seguente funzione:

extern uint32_t byteswap(uint32_t n);

La funzione riceve in input un intero senza segno a 32 bit in little endian e deve restituire,
sempre come intero senza segno a 32 bit, la sua rappresentazione in big endian. Ad esempio, dato
il numero intero espresso in esadecimale 0x0a0b0c0d, la funzione deve restituire il numero
0x0d0c0b0a
Se fosse stato in base dieci avrei preso il modulo ,ma in questo caso?
 
Se il problema è riordinare i byte, puoi usare gli operatori bitwise di shift e and logico.
Se sai che i byte sono 4 (32bit) puoi scrivere una cosa del genere:
C:
int main()
{
    unsigned int n = 0xaabbccdd;
    printf("%x\n", n);
    n = byteswap(n);
    printf("%x", n);
    return 0;
}

unsigned int byteswap(unsigned int n){
    unsigned int m = (n << 24); //sposta quarto byte
    m += (n << 8)&0x00ff0000; //sposta terzo byte
    m += (n >> 8)&0x0000ff00; //sposta secondo byte
    m += (n >> 24)&0x000000ff; //sposta primo byte
    return m;
}
che *dovrebbe* stampare
Codice:
aabbccdd
ddccbbaa

Nota: la conversione si potrebbe fare in una sola riga senza nemmeno dover dichiarare una variabile m. Se consideri che la somma in questo caso equivale a un or logico... ma questo viene "lasciato come esercizio" :asd:
 
Sisi infine l'ho compreso sembrava chissà cosa,sorry sto provando a fare altri esercizi sui byte e c'e uno che dice: dato un uint32_t contente 00Num1,2,3 devo estrarre i numeri e metterli in in tre variabili uint16_t e ho fatto così, ma non funziona sapresti diri come mai?
C:
#include"unpack.h"
extern void unpack_values(uint32_t pack, uint16_t *num1, uint16_t *num2, uint16_t *num3) {
    uint16_t temp;
    *num3 = 0;
    *num2 = 0;
    *num1 = 0;
    for (size_t i = 0; i < 3; i++) {
        switch (i) {
        case 0: {for (size_t j = 0; j < 16; j++) {
            temp = pack % 2;
           
            temp >>= 1;
            *num3 |= temp;
            pack /= 2;
        }
                break;
        }
        case 1: {for (size_t j = 0; j < 16; j++) {
            temp = pack % 2;
            temp >>= 1;
            *num2 |= temp;
            pack /= 2;
        }
                break;
        }
        case 3: {for (size_t j = 0; j < 16; j++) {
            temp = pack % 2;
            temp >>= 1;
            *num1 |= temp;
            pack /= 2;
        }
                break;
        }
        default: break;

        }
    }
}
 
Sisi infine l'ho compreso sembrava chissà cosa,sorry sto provando a fare altri esercizi sui byte e c'e uno che dice: dato un uint32_t contente 00Num1,2,3 devo estrarre i numeri e metterli in in tre variabili uint16_t
Non capisco la consegna dell'esercizio, cos'è che dovrebbe contenere quell'unsigned int nei suoi 4 byte?
 
Ok ora è più chiaro.
Il codice che hai proposto è inutilmente complesso, non capisco l'uso ne' dei cicli ne' dello switch e qui mi permetto di osservare che forse dovresti dare un bel ripassone a tutti gli argomenti sulle operazioni con i bit e pure sui cast.
Quello che chiede quell'esercizio si risolve in una funzione di tre righe:
C:
void unpack_values(uint32_t pack, uint16_t *num1, uint16_t *num2, uint16_t *num3){
    *num1 = (uint16_t)(pack >> 20)&0x3FF;
    *num2 = (uint16_t)(pack >> 10)&0x3FF;
    *num3 = (uint16_t)(pack >> 0)&0x3FF;
}
Il procedimento è molto semplice.
num1: devi shiftare tutti i bit a destra di 20 posizioni così che il bit meno significativo di num1 (il bit numero 20, appunto) finisca in posizione 0. A questo punto fai un cast esplicito a tipo uint16_t che ti tronca via i 16bit più significativi che non ti servono più (num1 ora sta occupando i bit nelle posizioni da 0 a 9). Come ultima cosa, "mascheri" il valore con un and logico con 0x3FF che corrisponde a 0000.0011.1111.1111 così tengo solo i 10 bit. Ed ecco il valore di num1.
num2: stessa identica cosa, ma lo shift è di 10 posizioni, sempre verso destra.
num3: il numero occupa già le posizioni da 0 a 9, quindi non serve lo shift (ho esplicitato shift di 0 per chiarezza).

Alcuni output:
Codice:
//0x00100803 = 00 | 0000000001 | 0000000010 | 0000000011
pack=100803 => n1=1 n2=2 n3=3
//0x1172c0aa = 00 | 0100010111 | 0010110000 | 0010101010
pack=1172c0aa => n1=279 n2=176 n3=170
https://onlinegdb.com/SkPCk8M47

ps: ho visto ora che nel testo dell'esercizio num1 è quello più a destra (indirizzo di memoria più basso), nel mio codice devi quindi invertire le assegnazioni di num1 e num3.
 
Ultima modifica:
Sempre tre righe: usi delle maschere per estrarre i tre numeri binari.

Inviato dal mio Nexus 5 utilizzando Tapatalk
 
Pubblicità
Pubblicità
Indietro
Top