【问题标题】:Inclusive range uniform_real_distribution包含范围 uniform_real_distribution
【发布时间】:2015-09-09 19:14:47
【问题描述】:

我正在尝试使用随机库。我知道这里有一个类似的问题:std::uniform_real_distribution inclusive range。从我读过的内容来看,它应该是 [0, 10)。我尝试拥有 [0, 10] 但我已经尝试了解决方案,但它对我不起作用。我不知道为什么。这是一段代码。

std::vector<int> vec;

int main()
{   
    const int min = 0;
    const int max = 10;
    std::random_device rd;
    std::mt19937 gen(rd());
    std::uniform_real_distribution<> dis(min, std::nextafter(max, INT_MAX));
    const int MAX = 10; 
    for (int i = 0; i < MAX; i++)
    {
        int t = dis(gen);
        vec.push_back(t);
    }
    for (auto& i : vec)
        std::cout << i << std::endl;
    system("pause");
    return 0;
}

我试过了:

std::uniform_real_distribution<> dis(min, std::nextafter(max, INT_MAX));
std::uniform_real_distribution<> dis{ 0, 10 };
std::uniform_real_distribution<> dis(min, max);

它只随机生成 0 到 9,并且不包括我想要的 10。我正在开发 VS2013。

【问题讨论】:

  • 实际分布应该是某种浮点数,而不是整数。起床 9.99999 而永远不会 10.0000 是一种明显的可能性,当填充到 int t 时将被截断为 9@
  • 你真的想要uniform_int_distribution吗? [0, 10] 上的 uniform_real_distribution 产生 10 的机会...非常小。
  • 换句话说:你说你想要的东西在统计上与你已经拥有的东西没有区别。

标签: c++ c++11 random


【解决方案1】:

std::uniform_real_distribution 以实数工作,而不是整数。因此,dis(gen); 的 Real 结果很可能在存储在 Integer int t 中时被截断。因为在 Real 域中可用的值是无限的,所以 10.0 不太可能在十次尝试中返回,即使返回,floating point inaccuracy 也可能将其变成 9.999999 或类似的值。

如果编译器的警告已打开,这将显示为浮点到整数精度丢失警告。

快速解决方案是

  1. 不要使用int来存储返回值
  2. 使用std::uniform_int_distribution 代替uniform_real_distribution。

【讨论】:

  • 我通过将返回值存储为双精度值来尝试解决方案一,但这不起作用。第二个解决方案效果很好。谢谢!
  • 我认为 FP 的不准确性不会将 10.0 变成 9.9999x,因为它可以完美表示。将 10.0/3 变成 3.33333 是真正的问题,因为 10.0/3 不能完美表示。
  • @MSalters 这是一个有趣的观点。必须检查数学,但没有计算出 10,它是 2 的一个很好的倍数,所以听起来很合理。
  • @user4581301:只有 1.01
猜你喜欢
  • 2013-04-19
  • 2016-06-29
  • 2014-11-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-08
  • 2014-01-19
相关资源
最近更新 更多