![]() |
TIPI DI DATO IN C - PARTE 1° |
![]() |
In un qualsiasi linguaggio di programmazione le informazioni per essere manipolate necessitano di zone di memoria dove possono essere temporaneamente salvate. Le variabili sono il meccanismo che consente di ottenere questo obbiettivo. Le variabili sono caratterizzate dal tipo che definisce il range (intervallo) di valori ammessi e il set (insieme) di operazioni possibili. In C i tipi di dato elementari disponibili sono:
Tipi testuali |
||
nome tipo | dichiarazione | dimensione |
char | char ch | 1 byte |
char [N] | char stringa[10] | 1 byte per il numero di elementi dell'array |
Tipi Numerici Interi |
||
nome tipo | dichiarazione | dimensione |
bool | bool x | 1 byte |
short | short sx | 2 byte |
long / int |
int x long y |
4 byte |
Tipi Numerici con Decimali |
||
nome tipo | dichiarazione | dimensione |
float | float a | 4 byte |
double | double d | 8 byte |
Tipi Numerici Complessi |
||
nome tipo | dichiarazione | dimensione |
float _Complex | float _Complex a | 8 byte |
double _Complex | double _Complex d | 16 byte |
In realtà, a seconda del compilatore C utilizzato la varietà dei tipi disponibili si amplia notevolmente. Ad esempio in DEV C++ i tipi elementari presenti sono molti di più come si vede nel seguente sorgente in C.
#include <stdio.h> int main(int argc, char *argv[]) { printf("###################################################\n"); printf("# T I P I D I D A T O I N D E V C + + #\n"); printf("###################################################\n\n"); printf("- Tipi Testuali: ----------------------------------\n"); printf(" char: %2d byte;\n",sizeof(char)); printf(" char [10]: %2d byte;\n",sizeof(char[10])); printf("---------------------------------------------------\n\n"); printf("- Tipi Numerici Interi: ---------------------------\n"); printf(" bool: %2d byte;\n",sizeof(bool)); printf(" short: %2d byte \n",sizeof(short)); printf(" unsigned short: %2d byte \n",sizeof(unsigned short)); printf(" signed short: %2d byte;\n",sizeof(signed short)); printf(" int: %2d byte \n",sizeof(int)); printf(" unsigned int: %2d byte \n",sizeof(unsigned int)); printf(" signed int: %2d byte \n",sizeof(signed int)); printf(" short int: %2d byte \n",sizeof(short int)); printf(" long int: %2d byte \n",sizeof(long int)); printf(" unsigned short int: %2d byte \n",sizeof(unsigned short int)); printf(" signed short int: %2d byte \n",sizeof(signed short int)); printf(" unsigned long int: %2d byte \n",sizeof(unsigned long int)); printf(" signed long int: %2d byte \n",sizeof(signed long int)); printf(" long long int: %2d byte;\n",sizeof(long long int)); printf(" long: %2d byte \n",sizeof(long)); printf(" unsigned long: %2d byte \n",sizeof(unsigned long)); printf(" signed long: %2d byte \n",sizeof(unsigned long)); printf(" long long: %2d byte \n",sizeof(long long)); printf(" unsigned long long: %2d byte \n",sizeof(unsigned long long)); printf(" signed long long: %2d byte;\n",sizeof(signed long long)); printf("---------------------------------------------------\n\n"); printf("- Tipi Numerici Decimali: --------------------------\n"); printf(" float: %2d byte;\n",sizeof(float)); printf(" double: %2d byte;\n",sizeof(double)); printf(" long double: %2d byte;\n",sizeof(long double)); printf("---------------------------------------------------\n\n"); printf("- Tipi Numerici Complessi : -----------------------\n"); printf(" float _Complex: %2d byte;\n",sizeof(float _Complex)); printf(" double _Complex: %2d byte;\n",sizeof(double _Complex)); printf(" long double _Complex: %2d byte;\n",sizeof(long double _Complex)); printf("---------------------------------------------------\n\n"); } |
La sua esecuzione produce questo output:
NOTE:
- La funzione C sizeof(Tipo)
consente di sapere la dimensione in byte di ogni
Tipo
di variabile.
- La funzione printf(Frase)
consente di stampare a video l'argomento "Frase"
L'occupazione
in byte di un tipo non è universale ma dipende dalle diverse architetture hardware
utilizzate e dalle numerose varianti di (compilatori) C esistenti. Ad esempio il tipo
Int occupa 32 bit con
alcuni compilatori
(esempio Dev C++) mentre in altri
Int
usa solo
16 bit (Ansi C).
NOTA: Il compilatore è quel programma che trasforma il sorgente testuale
(contenente le istruzioni in un determinato linguaggio) in eseguibile (contenente
istruzioni in assembler o codice macchina).
Tipo |
Macintosh |
Linux su PC |
IBM PC |
ANSI C Minimum |
char |
8 |
8 |
8 |
8 |
int |
32 |
32 |
32 |
16 |
short |
16 |
16 |
16 |
16 |
long |
32 |
32 |
32 |
32 |
long long |
64 |
64 |
64 |
64 |
Tipo |
Macintosh |
Linux su PC |
IBM PC |
ANSI C Minimum |
float |
6 digits |
6 digits |
6 digits |
6 digits |
|
–37 to 38 |
–37 to 38 |
–37 to 38 |
–37 to 37 |
double |
18 digits |
15 digits |
15 digits |
10 digits |
|
–4931 to 4932 |
–307 to 308 |
–307 to 308 |
–37 to 37 |
long double |
18 digits |
18 digits |
18 digits |
10 digits |
|
–4931 to 4932 |
–4931 to 4932 |
–4931 to 4932 |
–37 to 37 |
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 diversi tipi di dato elementare indicati all'inizio di questa pagina web.
L'eseguibile CreaFile.exe, appena scaricato, ci consente di generare 9 file. Il codice sorgente in C di CreaFile.exe è il seguente
#include <stdio.h> #define _Complex_I (0.0F + 1.0iF) int main(int argc, char *argv[]) { int n; FILE *fpo; // ################################################# // Definizione dei dati // ################################################# // Caratteri --------------------------------------- char ch='A'; // 1 Byte char stringa[]="ABCD"; // 4 Byte // Numerici interi --------------------------------- bool vero=true, falso=false; short sx=16961; // 65+66*256 int ix=1329678659; // 67+73*256+65*256^2+79*256^3 long long lx=0; // Numerici razionali ------------------------------- float f=3242803968.0002; double lf=61084138414899658000000000000000000000000000000000000000000000000000000000.0; // Numerici Complessi ------------------------------- float _Complex f_i=f+f*_Complex_I; double _Complex d_i=lf+lf*_Complex_I; // ################################################# // File di testo con 4 caratteri: AB // ################################################# fpo=fopen(".\\File_T_char.dat","w+"); ch='A'; // in ascii 65 putc(ch,fpo); ch=ch+1; // dovrebbe essere 66 => B putc(ch,fpo); ch=ch+1; // dovrebbe essere 67 => C putc(ch,fpo); ch=ch+1; // dovrebbe essere 68 => D putc(ch,fpo); fclose(fpo); // ################################################# // File testuale con Array di 4 caratteri: CIAO // ################################################# fpo=fopen(".\\File_T_string.dat","w+"); fprintf(fpo,"%s",stringa); fclose(fpo); // ################################################# // File binario contenente 4 boolean // ################################################# fpo=fopen(".\\File_NI_bool.dat","wb+"); n=fwrite(&vero,sizeof(vero),1,fpo); n=fwrite(&falso,sizeof(falso),1,fpo); n=fwrite(&falso,sizeof(falso),1,fpo); n=fwrite(&vero,sizeof(vero),1,fpo); fclose(fpo); // ################################################# // File binario contenente 2 short // ################################################# fpo=fopen(".\\File_NI_short.dat","wb+"); n=fwrite(&sx,sizeof(sx),1,fpo); sx=sx+1; n=fwrite(&sx,sizeof(sx),1,fpo); fclose(fpo); // ################################################# // File binario contenente 2 int // ################################################# fpo=fopen(".\\File_NI_int.dat","wb+"); n=fwrite(&ix,sizeof(ix),1,fpo); ix=ix+1; n=fwrite(&ix,sizeof(ix),1,fpo); fclose(fpo); // ################################################# // File binario contenente un float // ################################################# fpo=fopen(".\\File_NR_float.dat","wb+"); n=fwrite(&f,sizeof(f),1,fpo); fclose(fpo); // ################################################# // File binario contenente un double // ################################################# fpo=fopen(".\\File_NR_double.dat","wb+"); n=fwrite(&lf,sizeof(lf),1,fpo); fclose(fpo); // ################################################# // File binario contenente un numero complesso float // ################################################# fpo=fopen(".\\File_NR_floatcomplex.dat","wb+"); n=fwrite(&f_i,sizeof(f_i),1,fpo); fclose(fpo); // ################################################# // File binario contenente un numero complesso double // ################################################# fpo=fopen(".\\File_NR_doublecomplex.dat","wb+"); n=fwrite(&d_i,sizeof(d_i),1,fpo); fclose(fpo); printf("Files generati!"); } |
NOTE:
- La funzione C fopen(NomeFile,modo)
consente di creare/aprire un file
- La funzione C fwrite
consente di scrivere all'interno di un file
L'esecuzione del programma produce i seguenti files (si notino le dimensioni!) [videata dos]:
lo stesso elenco in windows viene così presentato (si notino le dimensioni!):
I files prodotti contenengono dati di tipo omogeneo ed esattamente:
Nome File | Contenuto | Codice in C per la creazione del file | |
File_T_char.dat dimensione = 4 byte |
4 caratteri ascii: 'A' 'B' 'C' e 'D' |
|
|
File_T_string.dat dimensione = 4 byte |
la stringa (array) "ABCD" |
|
|
File_NI_bool.dat dimensione = 4 byte |
contiene 4 valori booleani: true, false, false e true |
|
|
File_NI_short.dat dimensione = 4 byte |
due numeri short: il numero intero x = 16.961 =65+66 x 256 e il numero y = x+1 = 16.962 =66+66 x 256 |
|
|
File_NI_int.dat dimensione = 8 byte |
due numeri interi: il numero intero X= 1.329.678.659 = 67 x 2560+73 x 2561+65 x 2562+79 x 2563 e il numero Y = X+1 = 1.329.678.660 = 68 x 2560+73 x 2561+65 x 2562+79 x 2563 |
|
|
File_NR_float.dat dimensione = 4 byte |
il numero decimale 3.242.803.968,0002 |
|
|
File_NR_double.dat dimensione = 8 byte |
il numero decimale
y= 61084138414899658000000000000000000000000000 000000000000000000000000000000,0002; |
|
|
File_NR_floatcomplex.dat dimensione = 8 byte |
il numero complesso
3.242.803.968,0002+3.242.803.968,0002*I dove I è un valore t.c. I2=-1 |
|
|
File_NR_doublecomplex.dat dimensione = 16 byte |
il numero complesso y+y*I dove y è lo stesso numero decimale usato per i double. |
|
L'eseguibile VisualizzaFile.exe consente di
analizzare i contenuti dei singoli files appena prodotti. Il programma
visualizza i contenuti dei files 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]
- numeri interi short composti da coppie di byte [SHORT dump]
- numeri interi int
composti da coppie di byte [INT dump]
- numeri con virgola mobile float composti da 4 byte in rappresentazione
IEEE754 a 32 bit
[FLOAT dump]
Il sorgente in C di
VisualizzaFile.exe è il seguente:
#include <stdio.h> #include <stdlib.h> int s; static int r; void Invio(int p, int q) { r++; if (p<=0) return; if ( ( (r % q)==0) && (r!=0) ) printf("\n "); } void DumpFile(char *Nf) { unsigned char d; short sx; int x; int r=0; float f; int n=0; FILE *fpo; printf("################################################\n"); printf("# File: %s\n",Nf); printf("################################################\n"); fpo=fopen(Nf,"rb"); // Lettura in Esadecimale rewind(fpo); printf("- HEX dump :"); r=0; n = fread(&d, sizeof(char), 1, fpo); while (!feof(fpo)) { printf("[%02X] ",d); n = fread(&d, sizeof(char), 1, fpo); Invio(n,4); } printf("\n------------------------------------------------\n"); // Lettura in Decimale rewind(fpo); r=0; printf("- DECIMALE dump:"); n = fread(&d, sizeof(char), 1, fpo); while (!feof(fpo)) { printf("[%3d] ",d); n = fread(&d, sizeof(char), 1, fpo); Invio(n,4); } printf("\n------------------------------------------------\n"); if (s>10) { // Lettura in unsigned rewind(fpo); r=0; printf("- SIGN.DEC dump:"); n = fread(&d, sizeof(char), 1, fpo); while (!feof(fpo)) { printf("[%3d] ",(signed char)d); n = fread(&d, sizeof(char), 1, fpo); Invio(n,4); } printf("\n------------------------------------------------\n"); } // Lettura in Ascii rewind(fpo); r=0; printf("- ASCII dump :"); n = fread(&d, sizeof(char), 1, fpo); while (!feof(fpo)) { printf("[%c] ",d); n = fread(&d, sizeof(char), 1, fpo); Invio(n,4); } printf("\n------------------------------------------------\n"); // Lettura in SHORT rewind(fpo); r=0; printf("- SHORT dump :"); n = fread(&sx, sizeof(short), 1, fpo); while (n>0) { printf("[%hd] ",sx); n = fread(&sx, sizeof(short), 1, fpo); Invio(n,4); } printf("\n------------------------------------------------\n"); // Lettura in INT rewind(fpo); printf("- INT dump :"); r=0; n = fread(&x, sizeof(int), 1, fpo); while (n>0) { printf("[%d] ",x); n = fread(&x, sizeof(int), 1, fpo); Invio(n,2); } printf("\n------------------------------------------------\n"); if (s<10) { // Lettura in FLOAT rewind(fpo); r=0; printf("- FLOAT dump :"); n = fread(&f, sizeof(int), 1, fpo); while (n>0) { printf("[%lf] ",f); n = fread(&f, sizeof(int), 1, fpo); Invio(n,1); } printf("\n------------------------------------------------\n"); } fclose(fpo); } void AsciiTable() { int i,r=2; printf("-----------------------------------\n"); printf("| T A B E L L A A S C I I |\n"); printf("--+--------------------------------\n |"); for (i=0 ; i<16 ; printf(" %X",i++) ); printf("\n--+--------------------------------\n"); for (r=2 ; r < 16 ; r++) { printf(" %X|",r); for (i=0; i<16 ; i++) printf(" %c",r*16+i); printf("\n"); } printf("--+--------------------------------\n |"); for (i=0 ; i<16 ; printf(" %X",i++) ); printf("\n--+--------------------------------\n"); } int main(int argc, char *argv[]) { s=atoi(argv[1]); if (s==1) DumpFile(".\\File_T_char.dat"); else if (s==2) DumpFile(".\\File_T_string.dat"); else if (s==3) DumpFile(".\\File_NI_bool.dat"); else if (s==4) DumpFile(".\\File_NI_short.dat"); else if (s==5) DumpFile(".\\File_NI_int.dat"); else if (s==6) DumpFile(".\\File_NR_float.dat"); else if (s==7) DumpFile(".\\File_NR_double.dat"); else if (s==8) DumpFile(".\\File_NR_floatcomplex.dat"); else if (s==9) DumpFile(".\\File_NR_doublecomplex.dat"); else if (s==14) DumpFile(".\\File_NI_NegShort.dat"); else if (s==15) DumpFile(".\\File_NI_NegInt.dat"); else if (s==99) AsciiTable(); else { printf("Sintassi: VisualizzaFile |
NOTE:
- La funzione C fread(Variabile,nByte,.,idFile)
carica in
Variabile un numero di
byte
nByte letti dal file
idFile.
Analizziamo ora l'output prodotto da VisualizzaFile.exe per ogni singolo file
File_T_char.dat | |
OUTPUT | OSSERVAZIONI |
################################################ # File: .\File_T_char.dat ################################################ - HEX dump :[41] [42] [43] [44] ------------------------------------------------ - DECIMALE dump:[ 65] [ 66] [ 67] [ 68] ------------------------------------------------ - ASCII dump :[A] [B] [C] [D] ------------------------------------------------ - SHORT dump :[16961] [17475] ------------------------------------------------ - INT dump :[1145258561] ------------------------------------------------ - FLOAT dump :[781.035217] ------------------------------------------------ |
In giallo è evidenziata l'interpretazione
valida del file (contiene infatti la parola "ABCD").
Per interpretazione valida si intende che la scelta del tipo utilizzato durante la lettura è compatibile con quello utilizzato nella scrittura del dato. L'interpretazione valida consente di visualizzare correttamente il valore reale del dato registrato nel file. Ad esempio se per errore interpretassi il file "File_T_Char.dat" come sequenza di numeri int la lettura mi restituirebbe 11.452.558.561 che non corrisponde al valore reale che è stato salvato in origine: "ABCD". Le visualizzazioni in HEX e DECIMALE sono di tipo sistemistico e servono per analizzare i dati registrati qualora non si conosca il tipo originale usato durante il salvataggio dei file. Nella rappresentazione HEX la coppia di lettere può essere vista come la notazione in base 256. Nella lettura come
SHORT (ovvero uso una variabile short) i 4 byte del file vengono letti a due a due. In hex
quindi ho
[41][42] e [43][44]. In decimale ho [65][66] che corrisponde: 65+66*256=
16.961 mentre [67][68] corrisponde a: 67+68*256= 17.475. Si noti come la
sequenza dei
coefficienti nella registrazione in DOS/WIN, contrariamente alla notazione in base 256 vista in classe,
risulta essere ribaltata. In altre parole se il calcolatore registrasse
in notazione decimale (e non binaria) il numero (1239)10
verrebbe salvato come (9321)10 la rappresentazione FP originale è 0 10001000 10000110 100001001000001 che corrisponde alla notazione normalizzata (1,10000100100001101000100)2 x 29. Utilizzando nella pagina che decodifica IEEE754 la sequenza ribaltata [44][43][42][41] otteniamo il decimale (781,0352172851562) che è quello visualizzato nel FLOAT dump. |
File_T_string.dat | |
OUTPUT | OSSERVAZIONI |
################################################ # File: .\File_T_string.dat ################################################ - HEX dump :[41] [42] [43] [44] ------------------------------------------------ - DECIMALE dump:[ 65] [ 66] [ 67] [ 68] ------------------------------------------------ - ASCII dump :[A] [B] [C] [D] ------------------------------------------------ - SHORT dump :[16961] [17475] ------------------------------------------------ - INT dump :[1145258561] ------------------------------------------------ - FLOAT dump :[781.035217] ------------------------------------------------ |
In giallo è evidenziata l'interpretazione
valida del file (contiene infatti la parola "ABCD").
Questo esempio evidenzia come una parola (stringa) di N caratteri è equivalente alla sequenza dei singoli N caratteri (byte). |
File_NI_bool.dat | |
OUTPUT | OSSERVAZIONI |
################################################ # File: .\File_NI_bool.dat ################################################ - HEX dump :[01] [00] [00] [01] ------------------------------------------------ - DECIMALE dump:[ 1] [ 0] [ 0] [ 1] ------------------------------------------------ - ASCII dump :[☺] [ ] [ ] [☺] ------------------------------------------------ - SHORT dump :[1] [256] ------------------------------------------------ - INT dump :[16777217] ------------------------------------------------ - FLOAT dump :[0.000000] ------------------------------------------------ |
L'interpretazione
valida del file richiede l'utilizzo del tipo corretto bool.
Si noti che al valore true (vero) corrisponde al numero decimale uno mentre al false (falso) lo zero. Nell'ASCII dump la faccina è il simbolo associato al carattere ascii 1 mentre il 2° byte non si vede poiché contiene il carattere nullo (in c '\0' - in ascii 0) Nello SHORT dump (ovvero uso una variabile short) vedo il valore 1 e 256 infatti 1 x 2560+0 x 2561= 1 e 0 x 2560+1 x 2561 =256. Nello INT dump (ovvero uso una variabile int) vedo il numero 16.777.217. Infatti la variabile int utilizzata nella lettura carica 4 byte al colpo ovvero [1][0][0][1]. Sfruttando i criteri di rappresentazione in base 256 ottengo: 1 x 2560+0 x 2561 + 0 x 2562+1 x 2563 = 16.777.217 Nella lettura come FLOAT (ovvero uso una variabile float) i 4 byte del file vengono letti in un unico colpo. I 4 byte hex [01][00][00][01] vengono considerati come se fosse una notazione floating point. A questi 4 byte corrisponde quindi la seguente sequenza di 32 bit: 0 00000010 00000000000000000000001 che coincide con il decimale 1,0000001192092895 x 2-125 (che è 2,35 x 10-35 ~ 0). [Attenzione non ho ribaltato la sequenza di byte per ottenere la corretta rappresentazione FP semplicemente perché [01][00][00][01] è palindroma] |
File_NI_short.dat | |
OUTPUT | OSSERVAZIONI |
################################################ # File: .\File_NI_short.dat ################################################ - HEX dump :[41] [42] [42] [42] ------------------------------------------------ - DECIMALE dump:[ 65] [ 66] [ 66] [ 66] ------------------------------------------------ - ASCII dump :[A] [B] [B] [B] ------------------------------------------------ - SHORT dump :[16961] [16962] ------------------------------------------------ - INT dump :[1111638593] ------------------------------------------------ - FLOAT dump :[48.564701] ------------------------------------------------ |
In giallo è evidenziata l'interpretazione
corretta del file (contiene infatti i numeri interi: 16.961 e 16.962).
Riprendendo le stesse modalità viste in precedenza vediamo che
16.961 corrisponde alla sequenza di byte
in Ascii "AB"
(65 + 66 x 256)
mentre 16.962 a "BB"
(66 + 66 x 256).
Nella lettura come FLOAT
(ovvero uso una variabile float)
i 4 byte del file vengono letti in un
unico colpo ([41][42][42][42]) ed interpretati come se fosse
una notazione floating point (FP).
Come si è detto
in dos/win la sequenza di bit relativa a una rappresentazione numerica viene
salvata su disco partendo dal byte più a destra. Quindi se la
sequenza salvata è [41][42][42][42] la reale rappresentazione in FP è :
[42][42][42][41]. |
File_NI_int.dat | |
OUTPUT | OSSERVAZIONI |
################################################ # File: .\File_NI_int.dat ################################################ - HEX dump :[43] [49] [41] [4f] [44] [49] [41] [4f] ------------------------------------------------ - DECIMALE dump :[ 67] [ 73] [ 65] [ 79] [ 68] [ 73] [ 65] [ 79] ------------------------------------------------ - ASCII dump :[C] [I] [A] [O] [D] [I] [A] [O] ------------------------------------------------ - SHORT dump :[18755] [20289] [18756] [20289] ------------------------------------------------ - INT dump :[1329678659] [1329678660] ------------------------------------------------ - FLOAT dump :[3242803968.000000] [3242804224.000000] ------------------------------------------------ |
In giallo è evidenziata l'interpretazione
corretta del file (contiene il numero intero 1.329.678.659 e il suo successivo:
1.329.678.660). 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 originalmente
salvato. Questo perché i 4 byte che
compongono le rappresentazioni in base 256 dei numeri
1.329.678.659 e
1.329.678.660 interpretate come singoli byte corrispondono alla sequenza di
numeri decimali
[67][73][65][79]... che visti come codici ascii corrispondono ai simboli
presenti nelle stringhe
"CIAO" e
"DIAO".
Infatti: Nella lettura come SHORT (ovvero uso una variabile short) gli 8 byte del file vengono letti a due a due. In HEX per i primi 2 byte avrò la coppia [43][49]. In decimale diventa [67][73] che corrisponde in notazione 256 a: 67+73*256= 18.755. Per i successivi byte si può ripetere il procedimento appena visto ottenendo così la spiegazione dei valori mostrati nello SHORT Dump |
File_NR_float.dat | |||||||||||||||||||||||||
OUTPUT | OSSERVAZIONI | ||||||||||||||||||||||||
################################################ # File: .\File_NR_float.dat ################################################ - HEX dump :[43] [49] [41] [4F] ------------------------------------------------ - DECIMALE dump:[ 67] [ 73] [ 65] [ 79] ------------------------------------------------ - ASCII dump :[C] [I] [A] [O] ------------------------------------------------ - SHORT dump :[18755] [20289] ------------------------------------------------ - INT dump :[1329678659] ------------------------------------------------ - FLOAT dump :[3242803968.000000] ------------------------------------------------ |
In giallo è evidenziata l'interpretazione
corretta del file (contiene infatti il numero
3.242.803.968,0002). Il numero
3.242.803.968,0002 corrisponde alla
rappresentazione IEEE754 seguente (*): 0 10011110 10000010100100101000011 per cui la decodifica in ascii/hex diventa:
Si osservi che il valore originale registrato era
3.242.803.968,0002 mentre nel FLOAT dump viene riportato 3.242.803.968,000000.
L'errore è dovuto ad un underflow: la parte intera molto elevata con soli 32
bit porta ad una perdita di precisione nella parte decimale |
File_NR_double.dat | |||||||||||||||||||||||||||||||||||||||||||||||||
OUTPUT | OSSERVAZIONI | ||||||||||||||||||||||||||||||||||||||||||||||||
################################################ # File: .\File_NR_float.dat ################################################ - HEX dump :[43] [49] [41] [4F] ------------------------------------------------ - DECIMALE dump:[ 67] [ 73] [ 65] [ 79] ------------------------------------------------ - ASCII dump :[C] [I] [A] [O] ------------------------------------------------ - SHORT dump :[18755] [20289] ------------------------------------------------ - INT dump :[1329678659] ------------------------------------------------ - FLOAT dump :[3242803968.000000] ------------------------------------------------ |
II numero double originale registrato è
610841384148996580000000000000000000000000000000 00000000000000000000000000,0002. I dump proposti non forniscono la corretta interpretazione del dato poiché si fermano al float. Utilizziamo le stesse modalità viste per i float: la sequenza "CIAODIAO" in binario diviene (ribalto l'ordine del byte)
0.10011110100.0001010010010100010001001111010000010100100101000011
che corrisponde alla forma normalizzata: Utilizzando nella pagina che decodifica IEEE754 la sequenza ribaltata [4F][41][49][44][4F][41][49][44] otteniamo il decimale 6,108408449500632 x 1073. (il valore normalizzato è 1.0001010010010100001101001111010000010100100101000011 x 2245) |
File_NR_floatcomplex.dat e File_NR_floatcomplex.dat | |
OUTPUT | OSSERVAZIONI |
################################################ # File: .\File_NR_floatcomplex.dat ################################################ - HEX dump :[43] [49] [41] [4F] [43] [49] [41] [4F] ------------------------------------------------ - DECIMALE dump:[ 67] [ 73] [ 65] [ 79] [ 67] [ 73] [ 65] [ 79] ------------------------------------------------ - ASCII dump :[C] [I] [A] [O] [C] [I] [A] [O] ------------------------------------------------ - SHORT dump :[18755] [20289] [18755] [20289] ------------------------------------------------ - INT dump :[1329678659] [1329678659] ------------------------------------------------ - FLOAT dump :[3242803968.000000] [3242803968.000000] ------------------------------------------------ |
L'analisi dei files float/double _complex segue le stesse considerazioni viste per i float/double poiché i numeri
complessi vengono registrati separando la parte reale da quella immaginaria
in due valori numerici semplici di tipo float/double. La parte gialla corrisponde alla corretta interpretazione del file File_NR_floatcomplex.dat. Il primo numero è la parte reale mentre il secondo è la parte immaginaria del numero complesso salvato in origine.
Si osservi che la parte reale e quella immaginaria originali erano
3.242.803.968,0002 mentre nel FLOAT dump vedo 3.242.803.968,000000.
L'errore è dovuto ad un underflow: la parte intera molto elevata con 32
bit porta ad una perdita di precisione nella parte decimale |
OUTPUT | |
################################################ # File: .\File_NR_doublecomplex.dat ################################################ - HEX dump :[43] [49] [41] [4F] [44] [49] [41] [4F] [43] [49] [41] [4F] [44] [49] [41] [4F] ------------------------------------------------ - DECIMALE dump:[ 67] [ 73] [ 65] [ 79] [ 68] [ 73] [ 65] [ 79] [ 67] [ 73] [ 65] [ 79] [ 68] [ 73] [ 65] [ 79] ------------------------------------------------ - ASCII dump :[C] [I] [A] [O] [D] [I] [A] [O] [C] [I] [A] [O] [D] [I] [A] [O] ------------------------------------------------ - SHORT dump :[18755] [20289] [18756] [20289] [18755] [20289] [18756] [20289] ------------------------------------------------ - INT dump :[1329678659] [1329678660] [1329678659] [1329678660] ------------------------------------------------ - FLOAT dump :[3242803968.000000] [3242804224.000000] [3242803968.000000] [3242804224.000000] ------------------------------------------------ |