|
|
|
![]() |
|
Strumenti |
![]() |
#1 |
Member
Iscritto dal: Jan 2007
Messaggi: 173
|
[C] Estrazione bit
Salve, stavo provando a fare 1 esercizio ma mi risulta un po difficile, potreste aiutarmi? (scusate se rompo di nuovo)
![]() La traccia è: Scrivere 1 function C per estrarre dalla variabile intera A i k bit più o meno significativi dove k e A sono parametri di input usando (1) una maschera opportuna; (2) una maschera e operatori di shif (<< o >>) Già di per se la traccia non mi era chiara perchè la maschera non ho capito cos'è, poi per quanto riguarda l'estrazione nemmeno ho capito, cioè diciamo che io in input do' 4 in binario sarebbe 00000000.00000000.00000000.00000100 per estrarre i 3 piu' significativi devo estrarre questo in grassetto? 00000000.00000000.00000000.00000100? e le meno significative devo estrarre questo? 00000000.00000000.00000000.00000100? E che si intende per estrazione? Devono essere visualizzate solo quelle 3 cifre? Mi spieghereste pure cos'è una maschera? Scusate ma dalle slide della prof non si capisce ![]() |
![]() |
![]() |
![]() |
#2 |
Senior Member
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
|
La maschera è un intero che rappresentato in binario ha un 1 in tutti i bit che vuoi estrarre, ed uno 0 negli altri bit...
Se sai l'aritmetica binaria saprai che utilizzando l'and fra la maschera ed i dato, il risultato sarà composto da tutti zero dove la maschera ha zero e il valore del dato dove la maschera ha gli uno... I K bit meno significativi sono i K più a destra (nella notazione classica), i K più significativi sono i K più a sinistra... |
![]() |
![]() |
![]() |
#3 |
Senior Member
Iscritto dal: Nov 2005
Città: TO
Messaggi: 5206
|
No no. Dato un numero a N bit, il bit più significativo è quello più a sinistra (il bit N-1) e il meno significativo è quello più a destra (il bit 0).
__________________
Andrea, SCJP 5 (91%) - SCWCD 5 (94%) |
![]() |
![]() |
![]() |
#4 |
Member
Iscritto dal: Jan 2007
Messaggi: 173
|
ahhh, ok, capito, era piu' facile di quello che pensavo, credevo fosse chissà quale mostruosa cosa...
cmq ho scritto un po' il codice ma non va... ![]() mi da sempre lo stesso risultato X=65356 sara' per colpa di questo forse 5 n:\ciisem~1\lv1\4masch~1\maschera.c warning: return type of `main' is not `int' Codice:
#include <stdio.h> int PIU_SIGNIFICATIVI(int A,int k); int MENO_SIGNIFICATIVI(int A,int k); void main() { int A,k,X; short scelta; puts("Digita un valore A"); scanf("%d,&A"); puts("Digita quanti bit vuoi estrarre (max 32)"); scanf("%d,&k"); puts("Digita se estrarre i bit piu' significativi o meno significativi"); puts("Piu' significativi [0]"); puts("Meno significativi [1]"); scanf("%ld,&scelta"); while ((scelta==0 || scelta==1)) { puts ("Scelta errata, riprovare"); scanf("%ld,&scelta"); } if (scelta==0) X=PIU_SIGNIFICATIVI(A,k); else if (scelta==1) X=MENO_SIGNIFICATIVI(A,k); printf("Risultato X=%d\n",X); system("pause"); } int PIU_SIGNIFICATIVI(int A,int k) { int mask; short i; //Creazione maschera for (i=1;i<k;i++) mask=mask*2; mask--; mask<<(sizeof(int)*8-k); return mask&A; } int MENO_SIGNIFICATIVI(int A,int k) { short b; int mask=0; for(b=1;b<=k;b++) mask=mask<<1|1; return mask&A; } ![]() consigli? |
![]() |
![]() |
![]() |
#5 |
Senior Member
Iscritto dal: Nov 2005
Città: Texas
Messaggi: 1722
|
Ciao,
- per quanto riguarda il ciclo while, quello che hai scritto, in sintesi e': "se i dati sono corretti, ritenta". Probabilmente intendevi il contrario (a meno ovviamente di una svista mia); ![]() - Sarebbe meglio (ma e' solo un parere personale) se il bit meno significativo fosse 0 e non 1. Questo per due motivi: 1 - e' piu' semplice; 2 - fanno tutti cosi', per cui e' quello che ci si aspetta; - Il codice per MENO_SIGNIFICATIVI sembra OK. Il codice per PIU_SIGNIFICATIVI e' particolarmente strano. E' quello che non funziona? In piu' non hai inizializzato la mask, per cui il risultato sara' comunque indeterminato. Suggerimento: fai la stessa cosa di MENO_SIGNIFICATIVI, inizializzi la variabile mask a 0x80000000 e poi shift a destra Sottovento
__________________
In God we trust; all others bring data |
![]() |
![]() |
![]() |
#6 |
Senior Member
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
|
mask<<(sizeof(int)*8-k);
Questo operazione non fa niente dato che non hai assegnato il risultato... Inltre: mask=mask*2 equivale a fare: mask = mask << 1; Le maschere le puoi creare con gli shift... Data una maschera (che può avere già dei bit a 1) per aggiungere un 1 in una posizione qualsiasi devi fare lo shift sinistra del numero 1 di N posizioni corrispondenti al bit che vuoi a 1 e poi fare un or con la maschera... |
![]() |
![]() |
![]() |
#7 |
Member
Iscritto dal: Jan 2007
Messaggi: 173
|
grazie per gli aiuti, ho aggiustato il while, e per quanto riguarda sempre lo stesso risultato, avevo sbagliato un " nelle scanf (il compilatore mi sa che è vecchio non lo segnalava (dev 4)
ora il codice è cosi' Codice:
#include <stdio.h> int PIU_SIGNIFICATIVI(int A,int k); int MENO_SIGNIFICATIVI(int A,int k); void div_successive(int Numero_X, int base, int R_inv[], int *n); main() { int A,k,X,n,Array[32]; short i,scelta; puts("Digita un valore A"); scanf("%d",&A); puts("Digita quanti bit vuoi estrarre (max 32)"); scanf("%d",&k); puts("Digita se estrarre i bit piu' significativi o meno significativi"); puts("Meno significativi [0]"); puts("Piu' significativi [1]"); scanf("%hd",&scelta); while (!(scelta==0 || scelta==1)) { puts ("Scelta errata, riprovare"); scanf("%hd",&scelta); } if (scelta==0) X=MENO_SIGNIFICATIVI(A,k); else if (scelta==1) X=PIU_SIGNIFICATIVI(A,k); printf("Risultato decimale X=%d\n",X); div_successive (X,2,Array,&n); printf("Risultato binario X="); for (i=0;i<n;i++) printf("%d",Array[i]); printf("\n"); system("pause"); } int PIU_SIGNIFICATIVI(int A,int k) { int mask=1; short i,j; //Creazione maschera for (i=0;i<k;i++) mask=mask<<1; mask--; printf("Maschera_1: %d\n\n",mask); mask=mask<<(sizeof(int)*8-k); printf("Maschera_2: %d\n",mask); return mask&A; } int MENO_SIGNIFICATIVI(int A,int k) { short b; int mask=0; for(b=1;b<=k;b++) mask=mask<<1|1; return mask&A; } void div_successive(int Q, int B, int R_inv[], int *n) { int Q1,j,i; int R[30]; j=-1; /* Calcolo resti */ while (Q>0) { j+=1; Q1=Q/B; R[j]=Q-Q1*B; Q=Q1; } /* Inversione */ for (i=0;i<=j;i++) { R_inv[i]=R[j-i]; R_inv[j]=R[j-i]; } *n=j+1; } @cionci la maschera l'ho creata in 2 modi, questo mask=mask<<1|1; è quello che intendevi tu vero? @sottovento Perchè devo salvare la variabile mask a 0x80000000 e poi shiftare a destra? Non è piu' comodo il mio metodo? ![]() P.s. ma per mostrare i bit, non c'è un metodo piu' semplice di quella function per le divisioni successive enorme? |
![]() |
![]() |
![]() |
#8 | |
Senior Member
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
|
Quote:
for(b = 0; b < k; b++) mask |= 1 << b; Stai attento ai cicli for, in questo caso non cambia niente, ma non prendere l'abitudine di farli partire da 1 e farli arrivare a k...prendi invece l'abitudine di farli come ti ho scritto sopra... |
|
![]() |
![]() |
![]() |
#9 |
Senior Member
Iscritto dal: Nov 2005
Città: Texas
Messaggi: 1722
|
Codice:
int PIU_SIGNIFICATIVI(int A,int k) { return (unsigned)(((int)0x80000000 >> k) & A) >> (32 - k); }
__________________
In God we trust; all others bring data Ultima modifica di sottovento : 24-04-2007 alle 16:12. Motivo: dimenticato i cast |
![]() |
![]() |
![]() |
#10 | |
Senior Member
Iscritto dal: Nov 2005
Città: TO
Messaggi: 5206
|
Quote:
Più semplicemente: Codice:
int higher_bits (int value, int bits) { return (int)(((unsigned int) value) >> (32-bits)); }
__________________
Andrea, SCJP 5 (91%) - SCWCD 5 (94%) |
|
![]() |
![]() |
![]() |
#11 | |
Senior Member
Iscritto dal: Nov 2005
Città: Texas
Messaggi: 1722
|
Quote:
![]() A questo punto, compilatore permettendo, puoi togliere l'ultimo cast in ordine di esecuzione. Rischioso, pero'...
__________________
In God we trust; all others bring data |
|
![]() |
![]() |
![]() |
#12 |
Senior Member
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
|
Gli si chiedeva di usare una maschera
![]() |
![]() |
![]() |
![]() |
#13 |
Senior Member
Iscritto dal: Nov 2005
Città: Texas
Messaggi: 1722
|
Infatti c'e'.
Beh, nella soluzione ottima, quella di AndBin no, ma scommetto che il prof non c'aveva pensato...
__________________
In God we trust; all others bring data |
![]() |
![]() |
![]() |
#14 |
Member
Iscritto dal: Jan 2007
Messaggi: 173
|
grazie, quest'esercizio va sempre meglio
@andbin ottimo il tuo suggerimento, pero' devo usare la maschera, altrimenti non seguo il testo, cmq me lo sono segnato. @cionci si ho messo apposta quell'1 nel for perchè b era un contatore e un'indice di 1 array, cmq l'ho cambiato in 0, in effetti è sempre meglio partire da 0 @sottovento lol, troppo complicato ![]() cmq ora ho fatto cosi' e viene, l'errore credo fosse nel sizeof, infatti se metto 32 a mano, il risultato viene... Codice:
#include <stdio.h> int PIU_SIGNIFICATIVI(int A,int k); int MENO_SIGNIFICATIVI(int A,int k); void div_successive(int Numero_X, int base, int R_inv[], int *n); main() { int A,k,X,n,Array[32]; short i,scelta; puts("Digita un valore A (max 4294967295)"); scanf("%d",&A); puts("Digita quanti bit vuoi estrarre (max 32)"); scanf("%d",&k); puts("Digita se estrarre i bit piu' significativi o meno significativi"); puts("Meno significativi [0]"); puts("Piu' significativi [1]"); scanf("%hd",&scelta); while (!(scelta==0 || scelta==1)) { puts ("Scelta errata, riprovare"); scanf("%hd",&scelta); } if (scelta==0) X=MENO_SIGNIFICATIVI(A,k); else if (scelta==1) X=PIU_SIGNIFICATIVI(A,k); printf("Risultato decimale X=%u\n",X); div_successive (X,2,Array,&n); printf("Risultato binario X="); for (i=0;i<n;i++) printf("%d",Array[i]); printf("\n"); system("pause"); } int PIU_SIGNIFICATIVI(int A,int k) { int mask=1; //Creazione maschera mask=mask<<k; mask--; mask=mask<<(32-k); printf("%u",mask); printf("\n"); // return (int)(((unsigned int) A)>>(32-k)); return A&mask; } int MENO_SIGNIFICATIVI(int A,int k) { short b; int mask=0; for(b=0;b<k;b++) mask=mask<<1|1; return mask&A; } void div_successive(int Q, int B, int R_inv[], int *n) { int Q1,j,i; int R[30]; j=-1; /* Calcolo resti */ while (Q>0) { j+=1; Q1=Q/B; R[j]=Q-Q1*B; Q=Q1; } /* Inversione */ for (i=0;i<=j;i++) { R_inv[i]=R[j-i]; R_inv[j]=R[j-i]; } *n=j+1; } Tipo se deve scrivere 01000 scrive 1000, oppure se il numero è negativo (bit + significativo alto) la function non va perchè funziona solo per numeri maggiori di 0 (per via della condizione di questo while) Codice:
/* Calcolo resti */ while (Q>0) { j+=1; Q1=Q/B; R[j]=Q-Q1*B; Q=Q1; } ![]() Non potevano mettere direttamente un modo tipo %qualcosa? lol ![]() |
![]() |
![]() |
![]() |
#15 | ||
Senior Member
Iscritto dal: Nov 2005
Città: TO
Messaggi: 5206
|
Quote:
Quote:
In più vedi la mia risposta in <questo> thread.
__________________
Andrea, SCJP 5 (91%) - SCWCD 5 (94%) |
||
![]() |
![]() |
![]() |
#16 |
Member
Iscritto dal: Jan 2007
Messaggi: 173
|
Codice:
#include <stdio.h> int PIU_SIGNIFICATIVI(int A,int k); int MENO_SIGNIFICATIVI(int A,int k); void dec2bin(unsigned int inp, char binstr[32]); main() { int A,k,X,n; short i,scelta; char Array[32]; puts("Digita un valore A (max 4294967295)"); scanf("%d",&A); puts("Digita quanti bit vuoi estrarre (max 32)"); scanf("%d",&k); puts("Digita se estrarre i bit piu' significativi o meno significativi"); puts("Meno significativi [0]"); puts("Piu' significativi [1]"); scanf("%hd",&scelta); while (!(scelta==0 || scelta==1)) { puts ("Scelta errata, riprovare"); scanf("%hd",&scelta); } if (scelta==0) { X=MENO_SIGNIFICATIVI(A,k); dec2bin (X,Array); printf("Risultato binario X="); for (i=k-1;i>=0;i--) printf("%c",Array[i]); } else if (scelta==1) { X=PIU_SIGNIFICATIVI(A,k); dec2bin (X,Array); printf("Risultato binario X="); for (i=31;i>=(31-k);i--) printf("%c",Array[i]); } printf("\n"); system("pause"); } int PIU_SIGNIFICATIVI(int A,int k) { int mask=1; //Creazione maschera mask=mask<<k; mask--; mask=mask<<(32-k); // return (int)(((unsigned int) A)>>(32-k)); return A&mask; } int MENO_SIGNIFICATIVI(int A,int k) { short b; int mask=0; for(b=0;b<k;b++) mask=mask<<1|1; return mask&A; } void dec2bin(unsigned int inp, char binstr[32]) { int i; for (i = 0; i < 32; i++, inp >>= 1) binstr[i] = (inp & 1) + '0'; } ![]() @andbin carina la tua function per il dec2bin, molto compatta, peccato che pero' che non inverta pure l'array che deve essere stampato al contrario, altrimenti sarebbe perfetta ![]() |
![]() |
![]() |
![]() |
#17 | |
Senior Member
Iscritto dal: Nov 2005
Città: TO
Messaggi: 5206
|
Quote:
Vuoi gestire una stringa visualizzabile direttamente? Ecco: Codice:
void dec2bin(unsigned int inp, char *binstr) { int i; for (i = 0; i < 32; i++, inp >>= 1) binstr[31-i] = (inp & 1) + '0'; binstr[32] = '\0'; }
__________________
Andrea, SCJP 5 (91%) - SCWCD 5 (94%) |
|
![]() |
![]() |
![]() |
#18 |
Member
Iscritto dal: Jan 2007
Messaggi: 173
|
ah, ora vedendo il tuo codici vedo che in effetti è inutile invertire l'array di caratteri, basta salvarlo direttamente al contrario
Codice:
/* Scrivere 1 function C per estrarre dalla variabile intera A i k bit più o meno significativi dove k e A sono parametri di input usando (1) una maschera opportuna; (2) una maschera e operatori di shif (<< o >>) */ #include <stdio.h> int PIU_SIGNIFICATIVI(int A,int k); int MENO_SIGNIFICATIVI(int A,int k); void dec2bin(unsigned int inp, char binstr[32]); main() { int A,k,X,n; short i,scelta; char Array[32]; puts("Digita un valore A (max 4294967295)"); scanf("%d",&A); puts("Digita quanti bit vuoi estrarre (max 32)"); scanf("%d",&k); puts("Digita se estrarre i bit piu' significativi o meno significativi"); puts("Meno significativi [0]"); puts("Piu' significativi [1]"); scanf("%hd",&scelta); while (!(scelta==0 || scelta==1)) { puts ("Scelta errata, riprovare"); scanf("%hd",&scelta); } if (scelta==0) { X=MENO_SIGNIFICATIVI(A,k); dec2bin (X,Array); printf("Risultato binario X="); for (i=31;i>(31-k);i--) printf("%c",Array[i]); } else if (scelta==1) { X=PIU_SIGNIFICATIVI(A,k); dec2bin (X,Array); printf("Risultato binario X="); for (i=0;i<k;i++) printf("%c",Array[i]); } printf("\n"); system("pause"); } int PIU_SIGNIFICATIVI(int A,int k) { int mask=1; //Creazione maschera mask=mask<<k; mask--; mask=mask<<(32-k); // return (int)(((unsigned int) A)>>(32-k)); return A&mask; } int MENO_SIGNIFICATIVI(int A,int k) { short b; int mask=0; for(b=0;b<k;b++) mask=mask<<1|1; return mask&A; } void dec2bin(unsigned int inp, char binstr[32]) { int i; for (i = 0; i < 32; i++, inp >>= 1) binstr[31-i] = (inp & 1) + '0'; } ![]() Ultima modifica di k_mishima : 26-04-2007 alle 20:12. |
![]() |
![]() |
![]() |
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 19:27.