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

ilfe98

Moderatore
Staff Forum
Utente Èlite
3,052
1,278
CPU
Intel i7 7700K
Dissipatore
Bequiet Dark rock pro 4
Scheda Madre
Msi pc mate z270
HDD
Seagate barracuda 1tb, silicon power NVME 500gb
RAM
Patriot viper steel 3733Mhz
GPU
Inno 3d gtx 1080 herculez design
Monitor
Asus mg279q
PSU
Corsair HX750
Case
Itek lunar 23
Net
Tiscali ftth
OS
windows 10,mint,debian,Arch linux
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?
 

1nd33d

Utente Attivo
653
279
CPU
Intel i5 3570K @ 4,5Ghz
Dissipatore
Scythe Mugen 2
Scheda Madre
Gigabyte Z77X-UD3H
HDD
Samsung 840 PRO 256GB + Sandisk Ultra 250GB + Sandisk Plus 960GB
RAM
2x8GB Crucial Ballistix Tactical @2000Mhz CL9
GPU
XFX RX480 GTR Black Edition
Audio
Auzentech X-Fi Forte
Monitor
AOC i2369VW
PSU
Seasonic P660
Case
eh?
Periferiche
Razer Naga HEX v2
OS
Windows 10 64bit - Linux Mint 18
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:
 
  • Mi piace
Reazioni: ilfe98

ilfe98

Moderatore
Staff Forum
Utente Èlite
3,052
1,278
CPU
Intel i7 7700K
Dissipatore
Bequiet Dark rock pro 4
Scheda Madre
Msi pc mate z270
HDD
Seagate barracuda 1tb, silicon power NVME 500gb
RAM
Patriot viper steel 3733Mhz
GPU
Inno 3d gtx 1080 herculez design
Monitor
Asus mg279q
PSU
Corsair HX750
Case
Itek lunar 23
Net
Tiscali ftth
OS
windows 10,mint,debian,Arch linux
Aspetta come scusa? il numero sarà inviato dal prof non so quale numero avrò!
 

1nd33d

Utente Attivo
653
279
CPU
Intel i5 3570K @ 4,5Ghz
Dissipatore
Scythe Mugen 2
Scheda Madre
Gigabyte Z77X-UD3H
HDD
Samsung 840 PRO 256GB + Sandisk Ultra 250GB + Sandisk Plus 960GB
RAM
2x8GB Crucial Ballistix Tactical @2000Mhz CL9
GPU
XFX RX480 GTR Black Edition
Audio
Auzentech X-Fi Forte
Monitor
AOC i2369VW
PSU
Seasonic P660
Case
eh?
Periferiche
Razer Naga HEX v2
OS
Windows 10 64bit - Linux Mint 18
Aspetta come scusa? il numero sarà inviato dal prof non so quale numero avrò!
Ma... hai almeno letto il codice? La funzione byteswap la puoi chiamare con qualsiasi valore...
 

ilfe98

Moderatore
Staff Forum
Utente Èlite
3,052
1,278
CPU
Intel i7 7700K
Dissipatore
Bequiet Dark rock pro 4
Scheda Madre
Msi pc mate z270
HDD
Seagate barracuda 1tb, silicon power NVME 500gb
RAM
Patriot viper steel 3733Mhz
GPU
Inno 3d gtx 1080 herculez design
Monitor
Asus mg279q
PSU
Corsair HX750
Case
Itek lunar 23
Net
Tiscali ftth
OS
windows 10,mint,debian,Arch linux
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;

        }
    }
}
 

1nd33d

Utente Attivo
653
279
CPU
Intel i5 3570K @ 4,5Ghz
Dissipatore
Scythe Mugen 2
Scheda Madre
Gigabyte Z77X-UD3H
HDD
Samsung 840 PRO 256GB + Sandisk Ultra 250GB + Sandisk Plus 960GB
RAM
2x8GB Crucial Ballistix Tactical @2000Mhz CL9
GPU
XFX RX480 GTR Black Edition
Audio
Auzentech X-Fi Forte
Monitor
AOC i2369VW
PSU
Seasonic P660
Case
eh?
Periferiche
Razer Naga HEX v2
OS
Windows 10 64bit - Linux Mint 18
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?
 

ilfe98

Moderatore
Staff Forum
Utente Èlite
3,052
1,278
CPU
Intel i7 7700K
Dissipatore
Bequiet Dark rock pro 4
Scheda Madre
Msi pc mate z270
HDD
Seagate barracuda 1tb, silicon power NVME 500gb
RAM
Patriot viper steel 3733Mhz
GPU
Inno 3d gtx 1080 herculez design
Monitor
Asus mg279q
PSU
Corsair HX750
Case
Itek lunar 23
Net
Tiscali ftth
OS
windows 10,mint,debian,Arch linux

1nd33d

Utente Attivo
653
279
CPU
Intel i5 3570K @ 4,5Ghz
Dissipatore
Scythe Mugen 2
Scheda Madre
Gigabyte Z77X-UD3H
HDD
Samsung 840 PRO 256GB + Sandisk Ultra 250GB + Sandisk Plus 960GB
RAM
2x8GB Crucial Ballistix Tactical @2000Mhz CL9
GPU
XFX RX480 GTR Black Edition
Audio
Auzentech X-Fi Forte
Monitor
AOC i2369VW
PSU
Seasonic P660
Case
eh?
Periferiche
Razer Naga HEX v2
OS
Windows 10 64bit - Linux Mint 18
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:
  • Mi piace
Reazioni: ilfe98

ilfe98

Moderatore
Staff Forum
Utente Èlite
3,052
1,278
CPU
Intel i7 7700K
Dissipatore
Bequiet Dark rock pro 4
Scheda Madre
Msi pc mate z270
HDD
Seagate barracuda 1tb, silicon power NVME 500gb
RAM
Patriot viper steel 3733Mhz
GPU
Inno 3d gtx 1080 herculez design
Monitor
Asus mg279q
PSU
Corsair HX750
Case
Itek lunar 23
Net
Tiscali ftth
OS
windows 10,mint,debian,Arch linux
Chiaro ,grazie ancora
 

rctimelines

Utente Èlite
5,143
2,023
CPU
Ryzen 7 2700X | i7-6700k@4.5 | i5-4460... altri
Dissipatore
wraith MAX | Scythe Katana2|Arctic Freezer 11LP
Scheda Madre
Asrock B450 Fatal1ty 4K | Asus Prime Z270P | Acer Veriton
HDD
Samsung 970evo m.2 | vari | Samsung 860 evo
RAM
16GB G.Skill TridentZ 3000 | 16GB CORSAIR 2133 | 8GB DDR3 1600
GPU
RadeonPro WX3100 4G | ZOTAC GTX 1070 8G | Quadro k620 2G
Monitor
DELL 2419P 2K + Benq 17" | LG Ultrawide 27''
Net
fibra 1000
OS
Windows10-pro64/OpenSUSE-QL15.1/Debian 10.3
Sempre tre righe: usi delle maschere per estrarre i tre numeri binari.

Inviato dal mio Nexus 5 utilizzando Tapatalk
 

Ci sono discussioni simili a riguardo, dai un'occhiata!

Entra

oppure Accedi utilizzando
Discord Ufficiale Entra ora!

Discussioni Simili