21
votes

Apologies if this question has already been answered.

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

using namespace std;

int main () {

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

"implicit conversion loses integer precision: 'time_t' (aka 'long') to 'unsigned int'"

Is the error message Im getting when I execute the code above. I am using xcode 4.6.1. Now when I use a different complier such as the one from codepad.org it executes perfectly fine generating what seems like random numbers so I am assuming it is an xcode issue that I need to work around?

I have JUST started programming so I am a complete beginner when it comes to this. Is there a problem with my code or is it my complier?

Any help would be appreciated!

5
its not uncommon for longs to have more precision than unsigneds. - PlasmaHH

5 Answers

34
votes

"implicit conversion loses integer precision: 'time_t' (aka 'long') to 'unsigned int'"

You're losing precision implicitly because time() returns a long which is larger than an unsigned int on your target. In order to workaround this problem, you should explicitly cast the result (thus removing the "implicit precision loss"):

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

Given that it's now 2017, I'm editing this question to suggest that you consider the features provided by std::chrono::* defined in <chrono> as a part of C++11. Does your favorite compiler provide C++11? If not, it really should!

To get the current time, you should use:

#include <chrono>

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

Why should I bother with this when time() works?

IMO, just one reason is enough: clear, explicit types. When you deal with large programs among big enough teams, knowing whether the values passed around represent time intervals or "absolute" times, and what magnitudes is critical. With std::chrono you can design interfaces and data structures that are portable and skip out on the is-that-timeout-a-deadline-or-milliseconds-from-now-or-wait-was-it-seconds blues.

15
votes

As mentioned by "nio", a clean workaround would be to explicitly type cast.

Deeper explanation:

The srand() requires an unsigned int as parameter (srand(unsigned int)) but time() returns a long int (long int time()) and this is not accepted by the srand() so in order to fix this, the compiler has to simply typecast (convert) the "long int" to "unsigned int".

BUT in your case the compiler warns you about it instead (as the designers of the compiler thought you should be aware that's all).

So a simple

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

will do the trick!

(forgive me if i have done something wrong, this is my first answer on stackoverflow)

5
votes

The srand function has unsigned int as a type of argument, time_t is long type. the upper 4 bytes from long are stripped out, but there's no problem in it. srand will randomize the rand algorithm with 4 lower bytes of time, so you're supplying more data than is needed.

if you get an error, try to just explicitly cast the time_t type to unsigned int:

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

Another interesting thing is that if you run your program twice in the same second, you'll get the same random number, which can be sometimes undesired, that's because if you seed the rand algorithm with the same data, it will generate the same random sequence. Or it can be desirable when you debug some piece of code and need to test the same behaviour again... then you simply use something like srand(123456)

2
votes

This is not an error. The code is valid and its meaning is well defined; if a compiler refuses to compile it, the compiler does not conform to the language definition. More likely, it's a warning, and it's telling you that the compiler writer thinks that you might have made a mistake. If you insist on eliminating warning messages you could add a cast, as others have suggested. I'm not a big fan of rewriting valid, meaningful code in order to satisfy some compiler writer's notion of good style; I'd turn off the warning. If you do that, though, you might overlook other places where a conversion loses data that you didn't intend.

0
votes
#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;
}