web-dev-qa-db-fra.com

srand (time (null)) provoque un avertissement du compilateur: la conversion implicite perd la précision de l'entier

Excuses si cette question a déjà été répondu.

#include <iostream>
#include <cstdlib>
#include <ctime>

using namespace std;

int main () {

srand( time(NULL) );
cout << Rand();
}

"La conversion implicite perd la précision de l’entier: 'time_t' (ou 'long') en 'unsigned int' '"

Est-ce que le message d'erreur que je reçois lorsque j'exécute le code ci-dessus? J'utilise xcode 4.6.1. Maintenant, lorsque j’utilise un autre fournisseur tel que celui de codepad.org, il s’exécute parfaitement, générant ainsi des nombres aléatoires. Je suppose donc que c’est un problème de xcode sur lequel je dois travailler.

J’ai juste commencé à programmer, je suis donc un débutant en la matière. Y at-il un problème avec mon code ou est-ce mon complier? 

Toute aide serait appréciée! 

19
user2576878

"La conversion implicite perd la précision de l’entier: 'time_t' (ou 'long') en 'unsigned int' '"

Vous perdez implicitement la précision, car time() renvoie une long qui est supérieure à un unsigned int sur votre cible. Pour résoudre ce problème, vous devez explicitement convertir le résultat (en supprimant ainsi la "perte de précision implicite"):

srand( static_cast<unsigned int>(time(NULL)));

Étant donné que nous sommes en 2017, je modifie cette question pour vous suggérer de considérer les fonctionnalités fournies par std::chrono::* définies dans <chrono> dans le cadre de C++ 11. Votre compilateur préféré fournit-il C++ 11? Sinon, ça devrait vraiment!

Pour obtenir l'heure actuelle, vous devez utiliser:

#include <chrono>

void f() {
    const std::chrono::time_point current_time = std::chrono::system_clock::now();
}

Pourquoi devrais-je m'embêter avec ça quand time() fonctionne?

OMI, une seule raison suffit: des types clairs et explicites. Lorsque vous traitez avec de gros programmes parmi des équipes suffisamment grandes, vous devez savoir si les valeurs transmises représentent des intervalles de temps ou des temps "absolus", et quelles ampleurs sont essentielles. Avec std::chrono, vous pouvez concevoir des interfaces et des structures de données portables et ignorer le blues est-ce-que-un-délai-une-échéance-ou-millisecondes à partir de maintenant ou d'attendre-secondes.

28
Brian Cain

Comme mentionné par "nio", une solution de contournement serait de taper explicitement le transtypage.

Explication plus profonde:

Srand () nécessite un unsigned int en tant que paramètre (srand(unsigned int)) mais time () renvoie un long int (long int time()), ce qui n'est pas accepté par srand (). Pour résoudre ce problème, le compilateur doit simplement typecast (convertir) le "long int" à "unsigned int".

MAIS dans votre cas, le compilateur vous en avertit à la place (comme les concepteurs du compilateur pensaient que vous devriez être conscients que c'est tout).

Donc un simple

srand( (unsigned int) time(NULL) );

fera l'affaire!

(pardonnez-moi si j'ai fait quelque chose de mal, ceci est ma première réponse sur stackoverflow)

14
reubenjohn

La fonction srand a unsigned int en tant que type d'argument, time_t est un type long. les 4 octets supérieurs de long sont supprimés, mais il n'y a pas de problème . srand aléatoirement l'algorithme Rand avec 4 octets inférieurs, de sorte que vous fournissez plus de données que nécessaire.

si vous obtenez une erreur, essayez simplement de transtyper explicitement le type time_t en unsigned int:

srand( (unsigned int) time(NULL) );

Une autre chose intéressante est que si vous exécutez votre programme deux fois dans la même seconde, vous obtiendrez le même nombre aléatoire, ce qui peut parfois être indésirable, car si vous ensemencez l'algorithme Rand avec les mêmes données, il générera le même nombre aléatoire. séquence. Ou bien, il peut être souhaitable de déboguer une partie du code et de tester à nouveau le même comportement ... vous utilisez simplement quelque chose comme srand(123456)

5
nio

C'est pas une erreur. Le code est valide et sa signification est bien définie. si un compilateur refuse de le compiler, il ne se conforme pas à la définition du langage. Plus probablement, il s'agit d'un warning , et cela vous indique que l'auteur du compilateur pense que vous avez peut-être commis une erreur. Si vous insistez pour éliminer les messages d'avertissement, vous pouvez ajouter un casting, comme d'autres l'ont suggéré. Je ne suis pas un grand fan de la réécriture de code valide et significatif afin de satisfaire la notion de bon style de certains auteurs de compilateur; Je désactiverais l'avertissement. Si vous faites cela, cependant, vous pourriez oublier d'autres endroits où une conversion perd des données que vous n'aviez pas prévues.

2
Pete Becker
#include <stdlib.h>
#include <iostream>         //Rand
#include <time.h>       //time

float randomizer(int VarMin, int VarMax){
    srand((unsigned)time(NULL));
        int range = (VarMax - VarMin);
        float rnd = VarMin + float(range*(Rand()/(Rand_MAX + 1.0)));
return rnd;
}
0
BlueBit