TIPI DI DATO IN C - PARTE 2°


LABORATORIO: (clicca qui per scaricare i files necessari)

L'esercitazione vuole evidenziare le modalità di registrazione, all'interno di un un file DOS/WIN, dei numeri interi negativi.

L'eseguibile CreaFileNeg.exe, appena scaricato, ci consente di generare 2 files. Il codice sorgente in C di CreaFileNeg.exe è il seguente

#include <stdio.h>

int main(int argc, char *argv[])
{
    int n;
    FILE *fpo;

    // #################################################
    // Definizione dei dati	
    // #################################################
    // Numerici interi negativi ------------------------
    short sx=-24136;    // 184+161*256-256^2
    int ix=-1566531144; // 184+161*256+160*256^2+162*256^3-256^4

    // #################################################
    // File binario contenente 2 short
    // #################################################
    fpo=fopen(".\\File_NI_NegShort.dat","wb+");
    n=fwrite(&sx,sizeof(sx),1,fpo);
    sx=sx+232;
    n=fwrite(&sx,sizeof(sx),1,fpo);
    fclose(fpo);

    // #################################################
    // File binario contenente 2 int
    // #################################################
    fpo=fopen(".\\File_NI_NegInt.dat","wb+");
    n=fwrite(&ix,sizeof(ix),1,fpo);
    fclose(fpo);

    printf("Files generati!");
}

In C esistono due tipologie di interi: quelli con segno (espressi in complemento a 2) e quelli senza segno (in notazione binaria pura)

Tipi Numerici Interi con segno

nome tipo dichiarazione dimensione
short short sx 2 byte
long / int int x
long y
4 byte

Tipi Numerici Interi senza segno

nome tipo dichiarazione dimensione
unsigned short unsigned short usx 2 byte
unsigned int/long unsigned int ux
unsigned long uy
4 byte

L'esecuzione del programma produce i seguenti files (si notino le dimensioni!) [videata dos]:

I files prodotti contenengono dati di tipo omogeneo ed esattamente:

Nome File Contenuto Codice in C per la creazione del file
File_NI_NegShort.dat
dimensione = 4 byte
due numeri short negativi: il numero intero  x = -24.136 =184+161 x 256 - 1 x 2562 e il numero y = x+232 = -23.904 =160+162 x 256 - 1 x 2562
short sx=-24136;
fpo=fopen(".\\File_NI_NegShort.dat","wb+");
n=fwrite(&sx,sizeof(sx),1,fpo);
sx=sx+232;
n=fwrite(&sx,sizeof(sx),1,fpo);
fclose(fpo);
File_NI_NegInt.dat
dimensione = 4 byte
 
un solo numero intero negativo: il numero intero X= -1566531144 = 164 x 2560+161 x 2561+160 x 2562+162 x 2563 - 2564
int ix=-1566531144;
fpo=fopen(".\\File_NI_NegInt.dat","wb+");
n=fwrite(&ix,sizeof(ix),1,fpo);
fclose(fpo);

L'eseguibile VisualizzaFile.exe consente di analizzare i contenuti dei singoli file appena prodotti. Il programma visualizza i contenuti dei file interpretandoli come se fossero composti da sequenze di:
- byte (unsigned char) e li visualizza in:
    a) esadecimale [HEX dump]
    b) decimale [DECIMAL dump]
    c) sequenza di caratteri [ASCII dump]
- byte con segno (char) e li visualizza in:
    a) decimale con segno [SIGNED DECIMAL dump]
- numeri interi short composti da coppie di byte [SHORT dump]
- numeri interi int
 composti da coppie di byte [INT dump]

Il sorgente in C di VisualizzaFile.exe è lo stesso proposto nella prima parte del laboratorio.

Analizziamo ora l'output prodotto da VisualizzaFile.exe per ogni singolo file 

File_NI_NegShort.dat
OUTPUT OSSERVAZIONI
################################################
# File: .\File_NI_NegShort.dat
################################################
- HEX dump :[B8] [A1] [A0] [A2]
------------------------------------------------
- DECIMALE dump:[184] [161] [160] [162]
------------------------------------------------
- SIGN.DEC dump:[-72] [-95] [-96] [-94]
------------------------------------------------
- ASCII dump :[©] [í] [á] [ó]
------------------------------------------------
- SHORT dump :[-24136] [-23904]
------------------------------------------------
- INT dump :[-1566531144]
------------------------------------------------

In giallo è evidenziata l'interpretazione corretta del file (contiene infatti i numeri interi negativi: -24.136 e -23.904).  Utilizzando l'applicazione on line vediamo che i numeri -24.136 e -23.904 in complemento a 2 con 16 bit (2 byte) sono rispettivamente:
1010 00011011 1000 e 1010 00101010 0000
 
1010 0001 1011 1000 1010 0010 1010 0000
A 1 B 8 A 2 A 0
161 184 162 160
í © ó á

Nella lettura come SHORT (ovvero uso una variabile short) i 4 byte del file vengono letti a due a due. Nell HEX dump però leggo [B8][A1] e [A0][A2] invece della sequenza [A1][B8] e [A2][A0] corrispondente alla notazione in complemento a due appena calcolata.  Il motivo del ribaltamento dei byte è il solito:  in dos/win la sequenza di bit relativa ad una rappresentazione numerica viene salvata su disco partendo dal byte più a destra (meno significativo). Nel DECIMALE Dump vediamo [184][161] e [160][162]. Nell'esercitazione 1.2 abbiamo visto che la rappresentazione in complemento a 2 si basa su questa definizione generale: "dato un numero X rappresentato con N cifre in base B si definisce come suo complemento alla base la quantità (BN-X)". Nella notazione in complemento a 2 quindi [184][161] corrisponde a -(X) = Y-216 = (184 x 2560+ 161 x 2561 -2562) = -23.904. Analogamente [160][162] corrisponde a -(X) = Y-216 = (160 x 2560+ 162 x 2561 -2562) = -24.136.


File_NI_NegInt.dat
OUTPUT OSSERVAZIONI
################################################
# File: .\File_NI_NegInt.dat
################################################
- HEX dump :[B8] [A1] [A0] [A2]
------------------------------------------------
- DECIMALE dump:[184] [161] [160] [162]
------------------------------------------------
- SIGN.DEC dump:[-72] [-95] [-96] [-94]
------------------------------------------------
- ASCII dump :[©] [í] [á] [ó]
------------------------------------------------
- SHORT dump :[-24136] [-23904]
------------------------------------------------
- INT dump :[-1566531144]
------------------------------------------------

In giallo è evidenziata l'interpretazione corretta del file (contiene infatti un unico numero negativo: -1.566.531.144). Utilizzando l'applicazione on line vediamo che il numero -1.566.531.144 in complemento a 2 con 32 bit (4 byte) è:
1010 0010 1010 0000 1010 0001 1011 1000
 
1010 0010 1010 0000 1010 0001 1011 1000
A 2 A 0 A 1 B 8
162 160 161 184
ó á í ©

Nella lettura come INT (ovvero uso una variabile int) i 4 byte del file vengono letti tutti in un solo colpo. Nell HEX dump però leggo [B8][A1][A0][A2] invece della sequenza [A2][A0][A1][B8] corrispondente alla notazione in complemento a due appena calcolata.  Il motivo del ribaltamento dei byte è il solito:  in dos/win la sequenza di bit relativa ad una rappresentazione numerica viene salvata su disco partendo dal byte più a destra. Nel DECIMALE Dump ho [184][161][160][162]. Considerando la definizione del complemento alla base la notazione in complemento a 2 di [184][161][160][162] corrisponde a -(X) = Y-232 = (184 x 2560+ 161 x 2561+ 160 x 2562+ 162 x 2563 -2564) = -1.566.531.144.

Se provo ad aprire il file con il blocco note di windows (quindi interpreto il file come se fosse un testo) vedo:

che non corrisponde al valore numerico originalmente salvato. In realtà i byte del file vengono identificati come codici unicode 00B8 00A1 00A0 00A2. Possiamo replicarli manualmente nel block notes utilizzando la combinazione di tasti: ALT+0184 ALT+0161 ALT+0160 ALT+0162.

Il programma VisualizzaFile.exe visualizza (opzione 99) anche la tabella ascii