我目前正在研究重要性抽样,出于测试目的,我需要能够生成可能uniform_real_distribution<float>
为区间 [0,1] 生成的所有可能值(是的,它也从右侧关闭)。我的想法是生成整数,然后我可以将其转换为浮点数。从我所做的测试来看,[0,1] 中的统一单精度浮点数和 [0,2^24] 中的整数之间似乎存在完美的双射(我对它不是 [0 ,2^24-1] 并且我仍在试图找出原因,我最好的猜测是 0 对于浮点数来说只是特殊的,而 1 到 2^24 都会导致具有相同指数的浮点数)。我的问题是,以这种方式生成的浮点数是否正是可以从uniform_real_distribution<float>
. 你可以在下面找到我的整数 <-> 浮点测试:
void floatIntegerBitsBijectionTest()
{
uint32 two24 = 1 << 24;
bool bij24Bits = true;
float delta = float(1.0) / float(two24);
float prev = float(0) / float(two24);
for (uint32 i = 1; i <= two24; ++i)
{
float uintMap = float(i) / float(two24);
if (uintMap - prev != delta || uint32(uintMap*float(two24)) != i)
{
std::cout << "No bijection exists between uniform floats in [0,1] and integers in [0,2^24].\n";
bij24Bits = false;
break;
}
prev = uintMap;
}
if(bij24Bits) std::cout << "A bijection exists between uniform floats in [0,1] and integers in [0,2^24].\n";
std::cout << "\n";
uint32 two25 = 1 << 25;
bool bij25Bits = true;
delta = float(1.0) / float(two25);
prev = float(0) / float(two25);
for (uint32 i = 1; i <= two25; ++i)
{
float uintMap = float(i) / float(two25);
if (uintMap - prev != delta || uint32(uintMap*float(two25)) != i)
{
std::cout << "No bijection exists between uniform floats in [0,1] and integers in [0,2^25].\n";
if (i == ((1 << 24) + 1)) std::cout << "The first non-uniformly distributed float corresponds to the integer 2^24+1.\n";
bij25Bits = false;
break;
}
prev = uintMap;
}
if (bij25Bits) std::cout << "A bijection exists between uniform floats in [0,1] and integers in [0,2^25].\n";
std::cout << "\n";
bool bij25BitsS = true;
delta = 1.0f / float(two24);
prev = float(-two24) / float(two24);
for (int i = -two24+1; i <= two24; ++i)
{
float uintMap = float(i) / float(two24);
if (uintMap - prev != delta || int(uintMap*float(two24)) != i)
{
std::cout << i << " " << uintMap - prev << " " << delta << "\n";
std::cout << "No bijection exists between uniform floats in [-1,1] and integers in [-2^24,2^24].\n";
bij25BitsS = false;
break;
}
prev = uintMap;
}
if (bij25BitsS) std::cout << "A bijection exists between uniform floats in [-1,1] and integers in [-2^24,2^24].\n";
}
编辑:
有点相关:
http://xoroshiro.di.unimi.it/random_real.c
https://lemire.me/blog/2017/02/28/how-many-floating-point-numbers-are-in-the-interval-01/
编辑2:
我终于设法弄清楚uniform_real_distribution<float>
至少在mt19937
与默认模板参数一起使用时与引擎一起使用时会发生什么(我正在谈论 VS2017 附带的实现)。可悲的是,它只是在 [0,2^32-1] 中生成一个随机整数,然后将其转换为浮点数,然后除以 2^32。不用说,这会产生非均匀分布的浮点数。然而,我猜测这适用于大多数实际目的,除非一个工作接近生成数字之间的增量的精度。