2013-07-12 38 views
16

如果已经回答了此问题,请道歉。srand(time(null))会导致编译器警告:隐式转换失去整数精度

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

using namespace std; 

int main() { 

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

“的隐式转换失去整数精度:‘time_t的’(亦称‘长’),以‘无符号整型’”

是错误消息时,我执行上面的代码即时得到。我正在使用xcode 4.6.1。现在,当我使用不同的编译器,如来自codepad.org的编译器时,它会执行完美的生成似乎是随机数的东西,所以我认为这是一个需要解决的xcode问题?

我只是开始编程,所以我是一个完整的初学者,当谈到这一点。我的代码有问题还是我的编译器?

任何帮助,将不胜感激!

+1

它的情况并不少见渴望比unsigneds更精确。 – PlasmaHH

回答

25

“隐式转换损失整数精度:‘time_t的’(又名“长“),以‘无符号整型’”

你失去隐精度,因为time()返回long比你的目标的unsigned int大。为了解决这个问题,你应该明确地把结果(从而消除了“隐精度损失”):

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

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

为了得到当前的时间,你应该使用:

#include <chrono> 

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

我为什么要打扰这个时候time()作品?

IMO,只有一个理由就足够了:清晰,明确的类型。当你在足够大的团队中处理大型项目时,知道所传递的值是代表时间间隔还是“绝对”时间,以及什么样的量级至关重要。通过std::chrono,您可以设计可移植的接口和数据结构,并且可以跳过即将到期或即将到期或即将发生蓝屏的最后期限或毫秒超时。

+5

由于这个问题被标记为C++:_请不要使用C风格的强制转换。 'srand(static_cast (time(NULL));'工作得很好,并且让你的代码看起来非常漂亮有光泽,作为奖励,它避免了大量潜在的错误,这些错误可以通过C风格的演员发挥。 .. – ComicSansMS

+1

事实上,我不小心认为这是一个C问题,而没有看标签。Answer已编辑来纠正这个问题。 –

+1

它可能使用了一个不同的目标,其中一个目标是'long'和'unsigned int'(另一个编译器是用于32位机器的,这个可能是64位的) –

4

srand函数将unsigned int作为参数类型,time_t是long类型。从长的高4个字节被删除,但没有问题。 srand将用4个较低字节的时间随机化rand算法,所以你提供的数据比需要的要多。

,如果你得到一个错误,尽量只显式转换time_t的类型unsigned int类型:

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

另一个有趣的事情是,如果你在同一秒运行你的程序两次,你会得到相同的随机数,这可能有时是不受欢迎的,这是因为如果您将rand算法与相同的数据相结合,它将生成相同的随机序列。或者,也可以是理想的,当你调试一些代码段,需要再次测试相同的行为......那么你只需使用类似srand(123456)

2

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

+0

仅仅因为技术上正确的东西并不意味着它是一个好主意。在这种情况下,我更喜欢关闭一个编译器警告,这可能会在你更加粗心的时候保存你的培根 –

+0

@MarkRansom - 你是否会在一个平台上删除'time_t'和'无符号'是相同的大小,因为演员的原因不再适用?也许基于平台的条件,它?追逐警告可能是一个无底洞。 –

+0

我当然不会调整这样的演员阵容,如果我需要支持多个平台,我不会删除它。我现在可以看到它,但是将来有一天有人会来到StackOverflow并询问“为什么这些东西在没有做任何事情时投在这里?” –

13

正如“nio”所提到的,一个干净的解决方法是明确地键入强制转换。

更深的解释:

的srand()函数需要一个unsigned int作为参数(srand(unsigned int)),但时间()返回一个长整型(long int time()),这不是由函数srand接受(),因此,为了为了解决这个问题,编译器必须简单地将“long int”转换(转换)为“unsigned int”。 (编译器的设计者认为你应该意识到这一切)。编译器的设计者认为你应该知道这一切。

因此,一个简单

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

会做的伎俩!

(原谅我,如果我做错了什么,这是我的第一个计算器的答案)

+1

伟大的第一个答案! –

0
#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

我如何定制此函数以微秒生成随机数?用“srand((无符号)时间(NULL))”,这是不可能的!解决办法是什么? – BlueBit

+0

您可以使用像gettimeofday或GetSystemTimeAsFileTime这样的特定于平台的功能以亚秒精度返回时间。 – dan04

相关问题