Il problema è l'aggiunta. rand()restituisce un intvalore 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 intpuò 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 intprima dell'aggiunta se è possibile contenere la somma. Oppure usa un tipo più grande. Nota che longnon è necessariamente più ampio di int, lo stesso vale per long longse 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_MAXnon è possibile farlo int. Tuttavia, (unsigned int)rand() + 1lo 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é 11ci sono già due possibili varianti: 6 + 5o 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 ...