non riesco a risolvere questo esercizio:
acquisire due numeri A e B compresi tra 0 e 64000 e calcolare la somma dei "2" presenti nei numeri compresi tra A e B.
quindi se scegliessi i numeri 2001 e 2003, la catena di numeri da prendere in considerazione sarebbe : 2001 , 2002 , 2003 (A e B compresi ). in questa catena il numero "2" ricorre 4 volte quindi la somma totale dei numeri "2" è 8.
il programma andava svolto sia in c ( già fatto ) sia in assembler. in c ho scritto questo :
#include <stdio.h>
#define LIM_INF 0
#define LIM_SUP 64000
#define TARGET_DIGIT 2
int main(void) {
int A, B;
int contatore, curr;
//controllo dell'input
do { //ciclo che controlla se A < B
do { //ciclo che controlla se LIM_INF <= A <= LIM_SUP
printf("Inserisci estremo inferiore: ");
scanf("%d", &A);
} while (A < LIM_INF | A > LIM_SUP);
do { //ciclo che controlla se LIM_INF <= B <= LIM_SUP
printf("Inserisci estremo superiore: ");
scanf("%d", &B);
} while (B < LIM_INF || B > LIM_SUP);
} while (A > B);
for (contatore = 0; A <= B; A++)
//scompone il numero in cifre e cerca la cifra bersaglio (2 in questo caso)
for (curr = A; curr > 0; curr /= 10)
//ottengo cifra meno significativa e faccio quel che devo fare
if (curr % 10 == TARGET_DIGIT)
contatore++;
printf("Sono stati trovati %d cifre uguali a %d\n", contatore, TARGET_DIGIT);
printf("La somma delle %d occorrenze di %d e' %d\n", contatore, TARGET_DIGIT, TARGET_DIGIT * contatore);
return 0;
}
in assembler invece , dopo aver letto libri e guardato videolezioni ( partivo da 0 ) ho scritto questo , ma ho dei dubbi che sia giusto:
MOV CX,0 ; lo uso come contatore dei "2"
LOOP1:
MOV AX,SI ; mette il numero da testare in AX
LOOP2:
XOR DX,DX ; il dividendo è in DX:AX (numero a 32 bit) DX è sempre ZERO
MOV BX,10 ; il divisore
DIV BX ; divide DX:AX per BX, quoziente in AX, resto in DX (il resto è la cifra decimale)
CMP DX,2 ; se il resto è '2' allora abbiamo la cifra '2' nel numero
JNE NOT_DUE
INC CX ; incremento il contatore dei 2
NOT_DUE:
CMP AX,0 ; se il quoziente è ZERO ho finito col numero attuale
JNE LOOP2
INC SI ; passa al prossimo numero
CMP SI,DI ; se SI è minore/uguale a DI continua
JBE LOOP1
secondo me per capire se un numero ha, al suo interno, uno o più 2, il modo più semplice è trattarlo come stringa e analizzare carattere per carattere.
Ad esempio, se A=19 e B=31 , si inizia da A e :
- il carattere 1 è uguale al carattere 2? NO
- il carattere 9 è uguale al carattere 2? NO
- fine numero... allora, lo converto in numero (da '19' a 19), lo incremento (da 19 a 20) e poi lo riconverto in stringa (da 20 a '20') e rinizio il ciclo
- il carattere 2 è uguale al carattere 2? SI, allora sommo 2 a una variabile contatore
quindi non è vero, come ho scritto nei commenti, che se un numero è divisibile per 2 il resto della divisione per 10 deve essere 2 (se si prende il numero=21 si vede...). solo che ora non ho la più pallida idea di come scriverlo. potreste aiutarmi ???