Esempio di utilizzo della funzione per generare numeri casuali
// inizio file myrand.h
#include <stdlib.h>
int int_rand(int,int); //
generatore di numeri casuali di tipo intero
double doub_rand(double,double); // generatore
di numeri casuali di tipo double
int int_rand(int min,int max)
{int numero_casuale;
int differenza;
differenza = (max - min) + 1;
numero_casuale = rand() % differenza ;
numero_casuale = numero_casuale + min ;
return numero_casuale;
}
double doub_rand(double min,double
max)
{double numero_casuale,differenza;
differenza = (max - min);
numero_casuale = ((double) rand() /RAND_MAX) * differenza;
numero_casuale += min ;
return numero_casuale;
}
// fine file myrand.h
// inizio file sorgente
#include <stdio.h>
#include "myrand.h"
int main()
{int num,min,max;
srand(23847924); //
il compilatore, dove trova la dichiarazione di questa
funzione ?
min = 30;
max = 50;
printf("\ngenero un numero casuale compreso tra %d e %d\n",min,max);
num = int_rand(min,max);
printf("\n %d e\' compreso tra %d e %d\n",num,min,max);
return 0;}
// fine file sorgente
funziona ancora tutto con la seguente implementazione ?
// inizio file myrand.h
...
int int_rand(int min,int max)
{
int differenza;
differenza = (max - min) + 1;
max = rand() % differenza ;
max = max + min ;
return max ;
}
...
// fine file myrand.h
// inizio file sorgente
#include <stdio.h>
#include "myrand.h"
int main()
{int num,min,max;
srand(23847924);
min = 30;
max = 50;
printf("\ngenero un numero casuale compreso tra %d e %d\n",min,max);
num = int_rand(min,max);
printf("\n %d e\' compreso tra %d e %d\n",num,min,max);
// stampa ancora i valori corretti ??
printf("il valore della differenza tra min e max e\' %d",differenza);
// cosa stampa ?
return 0;}
// fine file sorgente
Prima di proseguire apriamo una piccola parentesi sulla rappresentazione
binaria dei caratteri. Prendiamo come riferimento il carattere 'y'. Il
codice ASCII di questo carattere è il 121 e questo valore, in rappresentazione
binaria, risulta pari a 01111001. La sequenza di bit si legge in questo
modo:
2^7 |
2^6 |
2^5 |
2^4 |
2^3 |
2^2 |
2^1 |
2^0 |
0 |
1 |
1 |
1 |
1 |
0 |
0 |
1 |
121 = 01111001 = 0 *
2^7 + 1 * 2^6 + 1 *
2^5 + 1 * 2^4 + 1 *
2^3 + 0 * 2^2 + 0 *
2^1 + 1 * 2^0
Come faccio a determinare qual è il valore del primo bit
a destra ? Il primo bit di destra indica se, nella rappresentazione
del numero in potenze di 2, compare anche il termine corrispondente alla
potenza di ordine 0, ovvero di 2^0 (= 1). Se quindi il numero è
pari tale contributo non compare, viceversa se il numero è dispari
tale contributo è presente.
Determinare il valore del primo bit equivale perciò a determinare
se il numero sia pari o dispari, informazione che possiamo ricavare a
parire dalla divisione per 2 con resto intero. In conclusione, dato un
numero intero num, il valore
num % 2
rappresenta il valore del primo bit a destra della sua rappresentazione
binaria.
Supponiamo ora di dividere il numero per una potenza di 2, ad esempio
per 2^3
121 / 2^3 = (0 * 2^7
+ 1 * 2^6 + 1 * 2^5
+ 1 * 2^4 + 1 * 2^3
+ 0 * 2^2 + 0 * 2^1
+ 1 * 2^0 ) / 2^3
= 0*2^4 + 1*2^3
+ 1*2^2 + 1*2^1 + 1*2^0
+ 0*0 + 0*0 + 1*0
Gli ultimi valori sono zero perché il rapporto risulta uguale ad
un numero decimale inferiore a 1 rappresentato come un intero (dato che
le potenze di 2 sono numeri interi).
Alla fine, quindi, ci rimane
121 / 2^3 = 0 * 2^4 + 1
* 2^3 + 1 * 2^2 + 1
* 2^1 + 1 * 2^0 = 15
2^7 |
2^6 |
2^5 |
2^4 |
2^3 |
2^2 |
2^1 |
2^0 |
0 |
0 |
0 |
0 |
1 |
1 |
1 |
1 |
NOTA : la rappresentazione binaria del numero è pari a
quella del valore iniziale, spostata verso destra di tre posizioni ! Ogni
divisione per 2 equivale ad uno spostamento a destra dei bit.
Questo ci permette di capire perché il valore di 1 / 2 (rappresentati
come interi) sia 0 e non 0.5 !
Se ora eseguo una divisione per 2 con resto intero ottengo il valore del
primo bit a destra; ma tale valore, dato che abbiamo appena eseguito uno
spostamento a destra della sequenza di bit di 3 posizioni non rappresenta
altro che il valore del bit che stava nella quarta posizione della rappresentazione
binaria del numero originale.
Abbiamo quindi trovato un metodo che ci permette di visualizzare
il valore di ogni singolo bit di cui è composta
una variabile di tipo intero o char. Ovvero, per visualizzare il bit che
si trova nella posizione corrispondente alla potenza di 2 di ordine nè
sufficiente dividere il numero per la corrispondente potenza di 2 e poi
calcolare il resto della divisione per 2.
Ad esempio:
num = 3423 = 00000000000000000000110101011111
se voglio il bit corrispondente alla potenza di ordine 6, ovvero il settimo
bit da destra, devo dividere per 2^6 (= 64)
3423 / 64 = 53
53 % 2 = 1
Costruiamo ed analizziamo ora un programma che impieghi le funzioni utili
a generare numeri casuali e stampi uno dei bit delle variabili.
Esercizio:
(1) chiedere all'utente di inserire due caratteri qualsiasi;
(2) usare tali caratteri per inizializzare il generatore di numeri casuali
utilizzando la funzione srand()
(3) generare un numero compreso tra 48 e 57 (ovvero il codice ASCII di
un carattere numerico)
(4) stampare il carattere corrispondente
(5) nel caso il carattere sia '5', stampare una scritta che notifichi
all'utente la cosa e calcolare il quadrato del numero rappresentato dal
carattere
(6) far generare un secondo numero casuale compreso tra 9.85 e 11.05
(7) elevare al quadrato tale valore casuale e stampare a video il carattere
corrispondente ed il suo codice ASCII
(8) stampare il terzo bit di tale carattere
Per preparare il codice mi servono:
(1) due variabili di tipo char ed una di tipo double
(2) stdio.h e printf per visualizzare i messaggi
(3) myrand.h e srand() per generare numeri
casuali
// inizio file sorgente
#include <stdio.h>
#include "myrand.h"
int main()
{char car1,car2;
double numero;
printf("\n inserire, uno di seguito all'altro, due caratteri");
car1 = getchar();
car2 = getchar();
srand(car1*car2); // inizializzo il generatore di numeri casuali
car1 = int_rand(48,57);
printf("\n\nil carattere ottenuto e\': %c",car1);
if(car1 == '5')
{printf("\n il carattere casuale e\' pari
a %c",car1);
printf("\n il quadrato del numero
corrispondente, %d, vale %d",car1-'0',(car1-'0')*(car1-'0'));
}
numero=doub_rand(9.85,11.05);
printf("\nil numero casuale ottenuto e\' %f",numero);
numero *= numero; // elevo al quadrato
printf("\n il suo quadrato vale %f",numero);
printf("\n il carattere corrispondente vale %c ed il codice
ASCII e\' %d",(int) numero,((int) numero)%256);
// perché serve il cast esplicito ? non era sufficiente
lo specificatore di formato ??
printf("\n il terzo bit del carattere vale %d",( (((int)
numero) % 256) / (2*2) ) %2);
return 0;}
// fine file sorgente
|