【问题标题】:How to generate random double numbers with high precision in C++?如何在 C++ 中生成高精度的随机双精度数?
【发布时间】:2013-08-10 11:53:49
【问题描述】:

我正在尝试生成一系列高精度的双随机数。例如,0.856365621(小数点后有 9 位)。

我从网上找到了一些方法,但是它们确实生成了双随机数,但精度没有我要求的那么好(小数点后只有6位)。

那么,我可以知道如何实现我的目标吗?

【问题讨论】:

  • 您能否演示您尝试过的方法,以便我们知道您尝试了什么。
  • 您确定您不只是打印具有默认 6 位精度的数字吗?
  • 您需要 52 个随机位来实现全双精度,因此您需要一个至少那么大的 PRNG,否则您必须多次调用较小的 PRNG 才能获得 at至少 52 位,那么您可以直接进行除法或将位移动到双精度值中。
  • “生成随机双打”通常充满问题。 0.25 和 0.5 之间的双精度数与 0.5 和 1.0 之间的双精度数一样多。得到结果x 的机会是否应该取决于x 的值?如果不是,则结果介于 0.25 和 0.5 之间的机会将等于结果介于 0.5 和 1 之间的机会。

标签: c++ random precision


【解决方案1】:

在 C++11 中,您可以使用 <random> header,在此特定示例中使用 std::uniform_real_distribution,我能够生成超过 6 位数的随机数。为了查看设置将通过std::cout 打印的位数,我们需要使用std::setprecision

#include <iostream>
#include <random>
#include <iomanip>    

int main()
{
    std::random_device rd;

    std::mt19937 e2(rd());

    std::uniform_real_distribution<> dist(1, 10);

    for( int i = 0 ; i < 10; ++i )
    {
       std::cout << std::fixed << std::setprecision(10) << dist(e2) << std::endl ;
    }

    return 0 ;
}

您可以使用std::numeric_limits::digits10 来确定可用的精度。

std::cout << std::numeric_limits<double>::digits10 << std::endl;

【讨论】:

  • 我也有类似的问题here如果可以的话你能帮帮我吗?
【解决方案2】:

在典型系统中,RAND_MAX 为 231-1 或类似的值。所以你的“精度”来自使用这样的方法:L

 double r = rand()/RAND_MAX;

将是1/(2&lt;sup&gt;31&lt;/sup)-1 - 这应该在随机数中为您提供 8-9 位“精度”。确保以足够高的精度打印:

 cout << r << endl;

不会。这样会更好:

 cout << fixed << sprecision(15) << r << endl; 

当然,有些系统的 RAND_MAX 小得多,在这种情况下,结果可能不太“精确” - 但是,您仍然应该在 9-12 范围内得到数字,只是它们更有可能要“相同”。

【讨论】:

    【解决方案3】:

    为什么不通过多次调用随机函数来创建您的价值呢?

    例如:

       const int numDecimals = 9;
    
       double result = 0.0;
       double div = 1.0;
       double mul = 1.0;
       for (int n = 0; n < numDecimals; ++n)
       {
          int t = rand() % 10;
          result += t * mul;
          mul *= 10.0;
          div /= 10.0;
       }    
       result = result * div;
    

    我会亲自尝试 rand 函数的新实现,或者至少乘以当前时间或其他东西..

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-02-11
      • 1970-01-01
      • 1970-01-01
      • 2018-11-27
      • 2012-05-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多