Sei sulla pagina 1di 10

2

Espressioni numeriche
 Composte da operatori, variabili, costanti e
Espressioni e funzioni, producono un valore
funzioni matematiche 


Delta = b*b-4*a*c;
Gli operatori matematici sono:
+ somma x = a + b;
- sottrazione x = a - b;
* moltiplicazione x = a * b;
Ver. 2.4 / divisione x = a / b;
% resto della divisione intera x = a % b;
 La divisione tra interi produce risultato intero
con troncamento della parte frazionaria
 Il resto può essere calcolato solo con
1
operandi di tipo intero (non floating-point)
© 2010 - Claudio Fornaro - Corso di programmazione in C

3 4

Precedenza degli operatori Associatività degli operatori


 Le regole di precedenza (o priorità) specificano  Le regole di associatività specificano in quale
in quale ordine vengono eseguiti i calcoli ordine vengono eseguiti i calcoli contenenti
 Raggruppati in livelli di priorità decrescente: operatori con lo stesso livello di precedenza
1. + –  segno  Per gli operatori matematici l’associatività è
2. () sempre da sinistra a destra
3. * / %  x=a+b+c;  x=(a+b)+c;
4. + –  somma e sottrazione x=a+b-c+d;  x=(((a+b)-c)+d);
 Esempi x=a*b/c;  x=(a*b)/c;
x = a+b*c;  prima la moltiplicazione x=a+b+c*d;  x=((a+b)+(c*d));
x = (a+b)*c;  prima la somma
x = a + -b;  a + (-b)
5
Espressioni numeriche 6

Overflow e altre eccezioni Operandi dello stesso tipo


 La gestione dell’overflow, della divisione per 0  Le operazioni matematiche possono essere
e delle altre eccezioni (errori al run-time) nella eseguite solo tra due operandi dello stesso
valutazione delle espressioni non è definita tipo (int con int, long con long, float
dal linguaggio (undefined behavior ), ma con float, double con double, etc.)
dipende dall’implementazione (ossia dal  I risultati intermedi dei calcoli vengono
compilatore) memorizzati in variabili temporanee (senza
nome) dello stesso tipo degli operandi
 Le variabili temporanee vengono rimosse
automaticamente dalla memoria dopo essere
state utilizzate

Espressioni numeriche 7
Espressioni numeriche 8

Operandi dello stesso tipo Operandi di tipo diverso


X = A + B * C  Le operazioni tra operandi di tipo diverso non
possono essere calcolate direttamente
 Dei due operandi, uno ha un tipo più ampio
 (capiente) dell’altro, ad es. il tipo double
può contenere qualsiasi valore di tipo float,
 che può contenere un long, che può
contenere un int
 Il valore del tipo meno capiente può essere
 e  sono le variabili temporanee convertito nell’altro tipo senza perdita
(ma con eventuale approssimazione, ad es.
se un long grande quale 1234567890 viene
convertito in float diventa 1.234567e9)
Espressioni numeriche 9
Espressioni numeriche 10

Operandi di tipo diverso Operandi di tipo diverso


 Questa conversione si chiama promozione e X = A d + Bd * C i Promozione
viene effettuata automaticamente
sull’operando del tipo meno capiente d
 La promozione crea una variabile temporanea
del tipo più capiente contenente il valore d
promosso (es. un 3 di tipo int viene
convertito in un 3.0 di tipo double)
d

La lettera d indica il tipo double, i il tipo int

Espressioni numeriche 11
Espressioni numeriche 12

Operandi di tipo diverso Operandi di tipo diverso


 La promozione avviene solo nel momento in  Attenzione
cui è necessaria per proseguire il calcolo Supponiamo gli int siano su 16 bit (max
X = Ad + B i * C i 32767) e i long su 32 bit (max 2 miliardi)
Il codice seguente dà risultato sbagliato
i (overflow) nel prodotto.
Promozione
int a, b;
d long c;
a = 30000;
b = 2;
d c = a * b;
Il calcolo tra B e C non richiede alcuna
promozione, a differenza di quello tra A ed  Perché?
Espressioni numeriche 13 14

Operandi di tipo diverso Conversione di tipo - cast


 Risposta:  L’operatore di cast produce una variabile
perché la variabile intermedia  è di tipo int temporanea del tipo indicato contenente il
e un int su 16 bit non può contenere 60000 valore originale convertito nel nuovo tipo (si
 Per risolvere il problema si deve far in modo di noti che la variabile originaria resta intatta)
avere una variabile intermedia di tipo long: (tipo)espressione
 definendo almeno una delle variabili di tipo long  Esempio
 oppure richiedendo esplicitamente la promozione a
c = (long)a
long di almeno una delle variabili  L’operatore di cast opera in modo simile alla
 La seconda soluzione è migliore: non richiede promozione, salvo che:
di cambiare il tipo delle variabili (è il risultato a  la conversione non è automatica, ma su richiesta
del programmatore
non essere rappresentabile, non gli operandi)
 il programmatore indica il tipo di dato voluto per la
variabile temporanea

15 16

Conversione di tipo - cast Conversione di tipo - cast


 Ha priorità maggiore degli operatori matem.  La conversione di un valore floating-point in
 La conversione di un valore da un tipo meno un valore intero avviene con troncamento
ampio ad uno più ampio preserva il valore della parte frazionaria, sempre che la parte
 La conversione di un valore da un tipo più intera sia rappresentabile con quel tipo
ampio a uno meno ampio può eliminare bit  Soluzioni dell’overflow in c=a*b :
significativi  possibile errore di conversione c = (long)a * b;  cast applicato ad a
Ad es. su una macchina con int a 16 bit: c = a * (long)b;  cast applicato a b
long x = 12345678L; c = (long)a * (long)b;
int y = (int)x; c = (long)(a*b);  INUTILE!
il cast dà risultato errato in quanto produce Nell’ultimo caso il cast viene applicato al
un valore fuori range per gli int (il max su risultato dell’operazione, ma è l’operazione
16 bit è 32767) stessa a dare problemi, non l’assegnazione a c
17 18

Promozioni integrali Conversioni nelle assegnazioni


 Nelle espressioni matematiche, i valori dei tipi  Quando un valore di un tipo viene assegnato
char e short int, i campi di bit e gli ad una variabile di un altro tipo, vi è una
elementi delle enum vengono implicita conversione del valore al tipo della
automaticamente convertiti: variabile da assegnare
 in int se questo tipo può rappresentare i valori  Poiché nella conversione di un valore da un
originali tipo più ampio ad uno meno ampio ci possono
 in unsigned int altrimenti essere i problemi indicati precedentemente, in
questi casi i compilatori attuano comunque la
conversione, ma in più alcuni (non tutti)
segnalano il problema con un warning
 Se l’assegnazione è comunque voluta si usi un
cast (anche per eliminare l’eventuale warning)

19 20

Conversioni nelle assegnazioni Overflow e Underflow


 Esempi  La gestione dell’overflow, della divisione per 0
(supponendo long su 32 bit e int su 16 bit) e delle altre eccezioni (errori al run-time) nella
int a, b=12; valutazione delle espressioni non è definita dal
long l=123456789; linguaggio (undefined behavior ), ma dipende
double e, f=3.0, g=9.275; dall’implementazione (ossia dal compilatore: in
a = f;  warning (a vale 3) alcuni sistemi vengono ignorati, in altri rilevati)
a = (int)f;  No warning (a vale 3)  In genere l’overflow prodotto da:
a = (int)g;  No warning (a vale 9)  interi con segno: viene ignorato
e = b;  No warning (e vale 12.0)  valori Floating-Point: produce il valore speciale INF
a = l;  warning (a vale ???) (infinito)
a = (int)l;  No warning (a vale ???)  divisione per 0: ferma il programma
21 22

Overflow e Underflow Operatori ++ e ––


 Per i valori senza segno, in caso di overflow il  Incrementano/decrementano di 1 una variabile:
C89 non indica un comportamento indefinito, ++a;
ma richiede espressamente che si seguano le  ++a incrementa a di 1 prima che a venga
utilizzata nel calcolo (incremento prefisso)
leggi dell’aritmetica modulo 2n:
 a++ incrementa a di 1 dopo che a è stata
 es. su 8 bit: 255+1=0 utilizzata nel calcolo (incremento postfisso)
infatti 11111111+1=00000000  ––a e a–– decrementano a di 1
 es. su 8 bit: 0–1=255 )  Esempi:
 Quando si sommano due numeri Floating-  a = 5;
Point e il rapporto tra i due è <223 (IEEE- x = ++a;
ora a vale 6 e x vale 6
P754 SP) o <252 (IEEE-P754 DP) si ha un
 a = 5;
Underflow, ossia il minore viene trascurato x = a++;
ora a vale 6 e x vale 5

23 24

Operatori ++ e –– Operatori di assegnamento


 Priorità maggiore degli operatori matematici  In C l’assegnazione è un’espressione e
 Utilizzabili solo con modifiable L-value dunque produce un risultato: il valore
(ossia un qualcosa che si può mettere a dell’espressione a destra del segno ‘=’
sinistra di un segno di assegnazione): ad es.  Questo e l’avere associatività da destra a
non si possono applicare al risultato di un sinistra permette di assegnare lo stesso valore
calcolo a più variabili con la scrittura seguente:
(a+1)++;  ERRORE a = b = c = 2;
 Attenzione che equivale a:
Le variabili usate con un operatore ++ o –– a = (b = (c = 2));
non possono apparire più di una volta nella
stessa espressione (fino al ; finale)
 x = i * i++;  Errore
25 26

Operatori di assegnamento Funzioni matematiche


 La forma di assegnamento:  Sono contenute in una libreria esterna al
variabile op= espressione compilatore, collegata all’eseguibile dal linker
essendo op un operatore del C, equivale a:  Richiedono che venga indicato il file di
variabile = variabile op espressione intestazione (header file) <math.h> che ne
x += 5; descrive la sintassi
equivale a x = x + 5;  Elaborano valori double (indicati tra
 Esiste per tutti gli operatori aritmetici e bitwise: parentesi) e producono risultati double
+= –= *= /= %= &= ^= |= <<= >>=
 Se i valori passati non sono di tipo double,
 Dopo aver visto i vettori: vengono automaticamente promossi a tale
vett[y%(x+2)] += 5; tipo (per effetto del prototipo <math.h>)
in questo esempio è evidente il vantaggio (di
digitazione e di computazione) di non dover  Le funzioni trigonometriche usano i radianti
scrivere due volte la quantità da incrementare (180o =  rad)

27 28

Funzioni matematiche Funzioni matematiche


sin(x)  seno pow(x,y)  xy (se y<0, x deve avere
cos(x)  coseno valore intero)
tan(x)  tangente sqrt(x)  radice quadrata (x  0)
asin(x)  arcoseno fabs(x)  valore assoluto
acos(x)  arcocoseno ceil(x)  minimo intero  x
atan(x)  arcotangente floor(x)  massimo intero  x
atan2(y,x)  arcotangente di y/x,  Esempi
maggiore precisione della y = sin(x*3.14/180);
precedente per x piccoli y = sin(x*2)*2;
exp(x)  esponenziale ex z = sqrt(fabs(x)*fabs(y));
log(x)  logaritmo naturale z = log(x)/log(2);
log10(x)  logaritmo in base 10 Pi = 4.0*atan(1.0);
29 30

Funzioni matematiche Funzioni matematiche


 Alcune altre funzioni matematiche sono  Per arrotondare un numero all’intero più
descritte nell’header file <stdlib.h>: vicino la libreria standard non dispone di
abs(x)  calcola il valore assoluto di un alcuna funzione
valore int e produce un risultato  Una soluzione statisticamente corretta
di tipo int richiede che i valori x.5 siano approssimati:
labs(x)  calcola il valore assoluto di un  se x è dispari: per eccesso (all’intero successivo)
valore long e produce un  se x è pari: per difetto (all’intero precedente)
risultato di tipo long –2.5  –2
–1.5  –2
+1.5  +2
+2.5  +2

31 32

Funzioni matematiche Valori casuali


 Una soluzione più semplice (ma non  La funzione rand ogni volta che viene
statisticamente corretta) è la seguente: chiamata produce un diverso valore intero
 Approssimazione sempre per eccesso compreso tra 0 e RAND_MAX (estremi inclusi)
 valori positivi:
con distribuzione uniforme
(int)(valore+0.5) x=rand();
 valori negativi:
 RAND_MAX vale almeno 32767 (il valore
(int)(valore-0.5) effettivo dipende dal compilatore)
 Approssimazione sempre per difetto  Le funzioni e le definizioni delle costanti
 valori positivi:
simboliche sono contenute in <stdlib.h>
(int)(valore+(0.5-DBL_EPSILON))  Per rendere effettivamente casuali i valori
 valori negativi:
generati, all’inizio del programma si aggiunga
(int)(valore-(0.5-DBL_EPSILON)) (una sola volta) l’istruzione:
srand(time(NULL));
(bisogna includere <time.h>)
33 34

Valori casuali Esercizi


 Per avere un valore intero tra 0 e N (escluso): 0. Disegnare il diagramma di valutazione della
x = rand() % N; seguente espressione, considerando le variabili
 In alcuni sistemi il generatore di numeri definite come segue:
pseudocasuali produce valori la cui parte float A,X;
bassa ha distribuzione poco uniforme, per cui int B,D;
può essere preferibile la formula : long C;
x = rand() / (RAND_MAX / N + 1); X=(A+4E2*B) * (C / 2) / atan(4.F * D);
 Per un esempio di funzione casuale con
distribuzione gaussiana si veda la citata FAQ
di Steve Summit (13.20)

35 36

Esercizi Esercizi
0. Soluzione (nei cerchi il tipo prodotto) 1. Scrivere un programma che chieda 4 numeri
( * (C / 2)) / atan(4.F * D); int, ne calcoli la media, la memorizzi in una
F D I L I D F I
X=(A+4E2*B)
prom. promozione prom.
variabile float e la visualizzi con 2 decimali.
D L F
prom.
/
2. Scrivere un programma che chieda un valore
* *
double di temperatura in gradi Fahrenheit e
D D L F
+
promozione
atan()
calcoli i valori delle corrispondenti
D D D temperature in gradi Celsius e Kelvin
*
(entrambi con parte frazionaria).
D
* 5
D C   ( F  32)
promozione
9
conversione
F K  C  273.15
37 38

Esercizi Esercizi
3. Un oggetto che si muove ad una velocità v 4. Si scriva un programma per calcolare la
confrontabile con quella della luce c distanza in linea d’aria tra due punti della
(2.99793·108 m/s) si accorcia (nel senso della superficie terrestre, note le coordinate
direzione) e aumenta di massa. Le due geografiche. Il programma chiede i valori di
grandezze sono (appropriatamente!)
modificate da un fattore  (minore di 1) pari a: latitudine (N-S) e di longitudine (E-O) in gradi
2
dei due punti. Per calcolare la distanza si usi
v la seguente formula (le coordinate Nord e Est
  1  
c sono positive, Sud e Ovest negative). Si
ricordi che le funzioni trigonometriche
Si scriva un programma che chieda la
lunghezza e la massa di un oggetto fermo e utilizzano i radianti.
calcoli la variazione delle due grandezze a distanza = arccos( p1+p2+p3 ) * r
quella velocità (richiesta in input in km/sec).

39 40

Esercizi Esercizi
(Continuazione) (Continuazione)
dove: Per la formula del arco-coseno non si utilizzi la
r è il raggio medio della Terra: 6372.795 km funzione di libreria acos, ma la seguente:
p1 = cos(lat1 )*cos(lon1 )*cos(lat2 )*cos(lon2 )
p2 = cos(lat1 )*sin(lon1 )*cos(lat2 )*sin(lon2 )  x  
arccos( x)  arctan 
p3 = sin(lat1 )*sin(lat2 ) 2 
essendo:  1 x  2
lat1 latitudine in gradi del primo punto Calcolare le distanze tra gli aeroporti di:
lon1 longitudine in gradi del primo punto  Torino (TRN, 45.02o N, 07.65o E)
lat2 latitudine in gradi del secondo punto  Roma (FCO, 41.81o N, 12.25o E)
lon2 longitudine in gradi del secondo punto  Los Angeles (LAX, 33.94o N, 118.40o W)
N.B. La formula considera la terra sferica con Nota:  = 4·tan-1(1)
raggio medio r : non essendolo, la formula dà [Risposte: TRN-FCO: 515.20 km, TRN-LAX: 9692.7 km,
un risultato con un errore massimo dello 0.5%. FCO-LAX: 10205.48 km]