首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >uniform_real_distribution<float>所有可能的值生成

uniform_real_distribution<float>所有可能的值生成
EN

Stack Overflow用户
提问于 2018-02-24 23:50:49
回答 1查看 2.3K关注 0票数 1

我目前正在进行重要性抽样,为了测试目的,我需要能够生成uniform_real_distribution<float>可能为间隔0,1生成的所有可能值。我的想法是生成整数,然后我可以转换成浮点数。从我所做的测试来看,在0,1中的均匀单精度浮点数和0,2^24中的整数之间似乎有一个完美的双射。我的问题是,以这种方式生成的浮点数是否正是可以从uniform_real_distribution<float>生成的浮点数。您可以在下面找到我的整数<->浮动测试:

代码语言:javascript
复制
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";
}

编辑:

有些相关:

https://crypto.stackexchange.com/questions/31657/uniformly-distributed-secure-floating-point-numbers-in-0-1

real.c

than/

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。不用说,这会产生非均匀分布的浮点数。不过,我猜想,除非一个人接近所生成的数字之间的差值的精度,否则这在大多数实际用途上是可行的。

EN

回答 1

Stack Overflow用户

发布于 2018-02-25 00:40:17

你可以强行解决这个问题。滚动你自己的随机浮动发电机。

编辑:我刚刚发现了std::generate_canonical<float>(),它做同样的事情,但不依赖于神奇的数字24。它可以从std::numerical_limits<float>::digits等.

代码语言:javascript
复制
#include <random>

static const unsigned long big = 1 << 24;
static std::default_random_engine re;
static std::uniform_int_distribution<unsigned long> uint(0, big - 1);

float rand_float() {
    return uint(re) / static_cast<float>(big);
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48968831

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档