C++优质随机数生成(自己写库尽可能接近真随机)

找抽,自己乱搞了一种生成方式

大家当个乐子看就行,正常东西在下面。

#include<bits/stdc++.h>
using namespace std;
template<int v>
class mygravity{
	unsigned long long f(unsigned long long h){
		double f=2*sqrt(h)/g*s;
		f-=(unsigned long long)(f)/360*360;
		f/=(double)(360)/v;
		unsigned long long k=(unsigned long long)(f);
		k^=(h<<17);k^=(h>>15);k^=h;k^=(h<<23);k^=(h>>29);k^=(h<<31);k^=(h>>37);k^=(h<<43);k^=(h>>47);k^=(h<<53);k^=(h>>57);k^=(h<<61);
		return k^(k<<48)^(k>>48)^(k<<16)^(k>>16);
	}
	unsigned long long re;const double s,g;
	public:
	mygravity(long long seed=-1,double rotat_speed=75.0,double Gravity_coefficient=0.98):re(seed),s(rotat_speed),g(Gravity_coefficient){
		if(seed==-1)re=(std::chrono::high_resolution_clock::now()).time_since_epoch().count()%10000*time(0);
	}
	unsigned long long max(){return ULONG_LONG_MAX;}
	unsigned long long min(){return 0;}
	unsigned long long operator()(){
		return (re=f(re));
	}
};
typedef mygravity<1000> mygravity_64;

大家们一般都和我这篇博客一样用取模在加的方式生成随机数,可这真的随机吗?

先不说生成器的分布问题,取模就会导致分布不均,所以我们就用这篇博客的方法来生成均匀分布的随机数,里面还有一些分布方式自取,我就不贴了。

浮点数均匀分布里面也有,但一般用的生成器范围够大,可以不用那篇博客的复杂方法。

这是我自己的生成算法和分布器:

#include<bits/stdc++.h>
using namespace std;
template<int v>
class mygravity{
	unsigned long long f(unsigned long long h){
		double f=2*sqrt(h)/g*s;
		f-=(unsigned long long)(f)/360*360;
		f/=(double)(360)/v;
		unsigned long long k=(unsigned long long)(f);
		k^=(h<<17);k^=(h>>15);k^=h;k^=(h<<23);k^=(h>>29);k^=(h<<31);k^=(h>>37);k^=(h<<43);k^=(h>>47);k^=(h<<53);k^=(h>>57);k^=(h<<61);
		return k^(k<<48)^(k>>48)^(k<<16)^(k>>16);
	}
	unsigned long long re;const double s,g;
	public:
	mygravity(long long seed=-1,double rotat_speed=75.0,double Gravity_coefficient=0.98):re(seed),s(rotat_speed),g(Gravity_coefficient){
		if(seed==-1)re=(std::chrono::high_resolution_clock::now()).time_since_epoch().count()%10000*time(0);
	}
	unsigned long long max(){return ULONG_LONG_MAX;}
	unsigned long long min(){return 0;}
	unsigned long long operator()(){
		return (re=f(re));
	}
};
typedef mygravity<1000> mygravity_64;
template<typename generator=mygravity<1000>> 
class myrandom{
	generator R;
	unsigned long long maxx,minn,g_len;
	public:
	myrandom():R(((std::chrono::high_resolution_clock::now()).time_since_epoch().count()%10000*time(0))){maxx=R.max(),minn=R.min();g_len=maxx-minn;}
	myrandom(long long x):R(x){maxx=R.max(),minn=R.min();g_len=maxx-minn;}
	long long operator()(long long l,long long r){
		unsigned long long u=r-l,w=0;
		if(g_len==u) return l+R();
		if(g_len>u){
			unsigned long long eu=u+1,s=g_len/eu,t=s*eu;
			do{
				w=R();
			}while(w>=t);
			w%=eu;
		}else{
			unsigned long long eg=g_len+1,s=u/eg;
			do{
				w=operator()((unsigned long long)0,s)*eg+R();
			}while(w>=u);
		}
		return l+w;
	} 
	template<typename T>
	T rand_int(T l,T r){
		typedef typename std::make_unsigned<T>::type U;
		U u=r-l,w=0;
		if(g_len==u) return l+R();
		if(g_len>u){
			U eu=u+1,s=g_len/eu,t=s*eu;
			do{
				w=R();
			}while(w>=t);
			w%=eu;
		}else{
			U eg=g_len+1,s=u/eg;
			do{
				w=rand_int<T>((U)0,s)*eg+R();
			}while(w>=u);
		}
		return l+w;
	}
	template<typename T>
	T rand_double(T l,T r){
		T x=T(maxx)-T(minn)+T(1);
		T x2=pow(10,floor(log10(x)));
		T dd=1,ans=0;
		while(dd>1E-20){
			ans+=dd*(R()/x);
			dd/=x2;
		}
		return l+ans*(r-l);
	}
	template<typename T>
	void shuffle(T l,T r){
		int len=r-l;
		for(int i=len-1;i>0;i--)swap(*(l+i),*(l+rand_int(0,i)));
	} 
	string rand_string(int siz,string character_set="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"){
		if(character_set.empty())return string(siz,'\0');
		string s;
		for(int i=0;i<siz;i++)s+=character_set[rand_int<int>(0,character_set.size()-1)];
		return s;
	}
};

支持随机整数,随机浮点数,在给定字符集中随机字符串,基于随机访问迭代器打乱。这里面只有 shuffle 是和大部分STL的函数一样左闭右开,别的都是左闭右闭的。

它的模板参数也可以用 mt19937 这种STL的random库的随机数引擎。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值