gianfard:
Cerco di rifletterci.
Come ha detto pure Standardoil, non c'è da riflettere, c'è solo da capire come funzion la cosa. Generalmente se hai operazioni in cui ci sono tipi numerici diversi, usa il formato più "ampio", ad esempio un "long" moltiplicato per un "int" dà un "long".
Quindi, per riepilogare prendendo alcuni dei tuoi esempi, se tu scrivi:
intVar = (234*142) / 250;
il compilatore iniza a valutare il contenuto, e dato che ci sono delle costanti intere lo interpreta così:
intVar = (int)( (int)( (int)234*(int)142 ) / (int)250 );
Ossia calcola per primo il valore tra parentesi come prodotto di interi quindi essendo un risultato necessariamente intero per via della mancanza di cast espliciti, va in overflow e ti sballa come hai già capito.
Quando invece fai:
intVar1=(234L*142) / 250;
che equivale esattamente a:
intVar3 = ( long(234)*142 ) / 250;
l'interpretazione diventa:
intVar = (int)( (long)((long)234*(int)142) / (int)250 );
e quindi in questo caso non "sballa" perché valuta 234*142 come prodotto di long per int cn risultato long (il tipo "più ampio").
Lasciando stare i float (se stai gestendo valori interi non ti conviene passare per i float che avendo solo una determinata precisione non mantengono sempre tutte le cifre), quando poi fai questo:
lngVar = (234*142) / 250;
la situazione non migliora perché viene valutato sempre allo stesso modo del primo, con l'unica diferenza che il valore finale "int" viene convertito in long:
lngVar = (long)( (int)((int)234*(int)142) / (int)250 );
Per cui devi far "capire" al compilatore che deve usare il tipo "long", il che significa che in questo caso la soluzione ideale, sapendo che comunque il risultato deve essere un "int", è:
int intVar1=(234L*142) / 250;
Se invece c'è il rischio che sia un long ti basta assegnarlo ad una variabile long:
long lngVar1=(234L*142) / 250;
E, per finire, se sai che devono essere valori positivi usa sempre "unsigned int" e "unsigned long".