C++ srand (time (null)) 导致编译器警告:隐式转换失去整数精度

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17618264/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 21:18:10  来源:igfitidea点击:

srand (time (null)) causes compiler warning: implicit conversion loses integer precision

c++compiler-warnings

提问by user2576878

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'"

“隐式转换失去整数精度:'time_t'(又名'long')到'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?

当我执行上面的代码时,我得到的错误消息是什么。我正在使用 xcode 4.6.1。现在,当我使用不同的编译器,例如来自 codepad.org 的编译器时,它执行得非常好,生成看起来像随机数的东西,所以我假设这是我需要解决的 xcode 问题?

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!

任何帮助,将不胜感激!

回答by Brian Cain

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

“隐式转换失去整数精度:'time_t'(又名'long')到'unsigned int'”

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

您正在隐式地失去精度,因为time()返回的 along大于unsigned int您的目标上的an 。为了解决这个问题,您应该显式转换结果(从而消除“隐式精度损失”):

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!

鉴于现在是 2017 年,我正在编辑这个问题以建议您考虑将std::chrono::*定义<chrono>为 C++11 的一部分提供的功能。你最喜欢的编译器提供 C++11 吗?如果没有,它真的应该!

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?

为什么我要在time()工作时费心呢?

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::chronoyou 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.

IMO,只有一个原因就足够了:清晰、明确的类型。当您在足够大的团队中处理大型程序时,了解传递的值是代表时间间隔还是“绝对”时间,以及大小是至关重要的。有了它,std::chrono您可以设计可移植的接口和数据结构,并跳过 is-that-timeout-a-deadline-or-milliseconds-from-now-or-wait-was-it-seconds blues。

回答by reubenjohn

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

正如“nio”所提到的,一个干净的解决方法是显式类型转换。

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".

srand() 需要一个 unsigned int 作为参数 ( srand(unsigned int)) 但 time() 返回一个 long int ( long int time()) 而这不被 srand() 接受,所以为了解决这个问题,编译器必须简单地类型转换(转换)“ long int”到“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) );

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

will do the trick!

会做的伎俩!

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

(如果我做错了什么,请原谅我,这是我在 stackoverflow 上的第一个答案)

回答by nio

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.

srand 函数有 unsigned int 作为参数类型,time_t 是 long 类型。long 的前 4 个字节被剥离,但没有问题。srand 会将 rand 算法随机化为 4 个较低字节的时间,因此您提供的数据比所需的多。

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

如果出现错误,请尝试将 time_t 类型显式转换为 unsigned int:

srand( (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)

另一个有趣的事情是,如果你在同一秒内运行你的程序两次,你会得到相同的随机数,这有时可能是不受欢迎的,那是因为如果你用相同的数据播种 rand 算法,它会生成相同的随机数序列。或者,当您调试一些代码并需要再次测试相同的行为时,它可能是可取的……然后您只需使用类似的东西srand(123456)

回答by Pete Becker

This is notan 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.

不是错误。代码有效,含义明确;如果编译器拒绝编译它,则编译器不符合语言定义。更有可能的是,这是一个警告,它告诉您编译器作者认为您可能犯了错误。如果您坚持消除警告消息,您可以像其他人建议的那样添加演员表。我不太喜欢重写有效的、有意义的代码以满足某些编译器作者的良好风格的概念;我会关闭警告。但是,如果您这样做,您可能会忽略转换会丢失您不想要的数据的其他地方。

回答by BlueBit

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