关于srand和rand的跨平台问题

在VS环境下,stdlib.h中有如下定义:

 

/* Maximum value that can be returned by the rand function. */

#define RAND_MAX 0x7fff

 

在rand.c中实现:

 

void __cdecl srand (
        unsigned int seed
        )
{
        _getptd()->_holdrand = (unsigned long)seed;
}

 

int __cdecl rand (
        void
        )
{
        _ptiddata ptd = _getptd();

        return( ((ptd->_holdrand = ptd->_holdrand * 214013L
            + 2531011L) >> 16) & 0x7fff );
}

 

可以看到,VS下该函数无论如何最大只返回65535/2;

 

而在gcc下,stdlib.h中则定义为:

 

128 /* The largest number rand will return (same as INT_MAX).  */
129 #define RAND_MAX    2147483647

 

源代码在glibc中;


下面一段代码,处理了这两种平台的差异:

 

 srand( time(NULL) );

 bool bScale = (RAND_MAX <= 65535);

 std::set<unsigned int> setIndex;
 for (int i = 0; i < 500; i ++)
 {
  unsigned int uNumRand = rand();
  if (bScale)
  {
   uNumRand *= 65535;
  }
  setIndex.insert( uNumRand % 1000000 );
 }

 

以上的第2中方法我这里有调试过,但是不太正确,还不明白为什么,但是下面的代码是关于gcc的rand的相关实现,代码经过测试,和gcc下编译出来的结果是一致的

 

【C语言库函数源代码】

【本程序在Dev C++ 4.9.9.2 下编译通过】

/*

   这两个函数是C库中产生随机数的程序。你需要先

   使用srand()函数赋随机数种子值。然后再使用

   rand()函数来产生随机数。但是产生随机数的算法

   较简单,srandom()和random()函数是对这两个函数

   的改良,用法也很类似。

*/

#define RANDOM_MAX 0x7FFFFFFF

static long my_do_rand(unsigned long *value)

{

/*

      这个算法保证所产生的值不会超过(2^31 - 1)

这里(2^31 - 1)就是 0x7FFFFFFF。而 0x7FFFFFFF

      等于127773 * (7^5) + 2836,7^5 = 16807。

      整个算法是通过:t = (7^5 * t) mod (2^31 - 1)

      这个公式来计算随机值,并且把这次得到的值,作为

下次计算的随机种子值。

   */

   long quotient, remainder, t;

 

   quotient = *value / 127773L;

   remainder = *value % 127773L;

   t = 16807L * remainder - 2836L * quotient;

 

   if (t <= 0)

      t += 0x7FFFFFFFL;

  return ((*value = t) % ((unsigned long)RANDOM_MAX + 1));

}

static unsigned long next = 1;

int my_rand(void)

{

   return my_do_rand(&next);

}

void my_srand(unsigned int seed)

{

   next = seed;

}

#include <time.h>

int main()

{

   int i;

  

   my_srand((unsigned)(time(NULL)));

   for(i=0;i<100;i++)

   {

      if(i % 10 == 0)

         printf("\n");

      printf("%d\t",my_rand()%99+1);

   }

   system("pause");

   return 0;

}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值