Il problema è l'aggiunta. rand()
restituisce un int
valore di 0...RAND_MAX
. Quindi, se ne aggiungi due, ti alzi RAND_MAX * 2
. Se questo supera INT_MAX
, il risultato dell'aggiunta trabocca nell'intervallo valido che int
può essere mantenuto. L'overflow dei valori firmati è un comportamento indefinito e può portare la tua tastiera a parlarti in lingue straniere.
Dato che qui non c'è alcun vantaggio nell'aggiungere due risultati casuali, l'idea semplice è semplicemente di non farlo. In alternativa è possibile eseguire il cast di ogni risultato unsigned int
prima dell'aggiunta se è possibile contenere la somma. Oppure usa un tipo più grande. Nota che long
non è necessariamente più ampio di int
, lo stesso vale per long long
se int
è almeno 64 bit!
Conclusione: basta evitare l'aggiunta. Non fornisce più "casualità". Se sono necessari più bit, è possibile concatenare i valori sum = a + b * (RAND_MAX + 1)
, ma probabilmente è necessario un tipo di dati più grande di int
.
Poiché il motivo dichiarato è quello di evitare un risultato zero: ciò non può essere evitato aggiungendo i risultati di due rand()
chiamate, poiché entrambi possono essere zero. Invece, puoi semplicemente incrementare. Se RAND_MAX == INT_MAX
non è possibile farlo int
. Tuttavia, (unsigned int)rand() + 1
lo farà molto, molto probabilmente. Probabile (non definitivamente), perché lo richiede UINT_MAX > INT_MAX
, il che è vero su tutte le implementazioni di cui sono a conoscenza (che copre alcune architetture embedded, DSP e tutte le piattaforme desktop, mobili e server degli ultimi 30 anni).
Avvertimento:
Sebbene sia già cosparso nei commenti qui, tieni presente che l'aggiunta di due valori casuali non ottiene una distribuzione uniforme, ma una distribuzione triangolare come il lancio di due dadi: per ottenere 12
(due dadi) entrambi i dadi devono mostrare 6
. perché 11
ci sono già due possibili varianti: 6 + 5
o 5 + 6
, ecc.
Quindi, anche l'aggiunta è negativa da questo aspetto.
Si noti inoltre che i risultati rand()
generati non sono indipendenti l'uno dall'altro, poiché sono generati da un generatore di numeri pseudocasuali . Si noti inoltre che lo standard non specifica la qualità o la distribuzione uniforme dei valori calcolati.
rand()
non può essere negativo ...