如何在C++中以高精度生成随机双精度数
How to generate random double numbers with high precision in C++?
>我正在尝试以高精度生成许多双随机数系列。例如,0.856365621(小数后有 9 位数字(。
我从互联网上找到了一些方法,但是,它们确实会生成双随机数,但精度不如我要求的那么好(小数点后只有 6 位数字(。
因此,我可以知道如何实现我的目标吗?
在 C++11 中,您可以使用 <random>
标头,在此特定示例中使用 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;
在典型的系统中,RAND_MAX是 231-1 或类似的东西。因此,使用诸如L之类的方法的"精度">
double r = rand()/RAND_MAX;
会1/(2<sup>31</sup)-1
- 这应该在随机数中为您提供 8-9 位"精度"。确保以足够高的精度打印:
cout << r << endl;
不行。这将更好地工作:
cout << fixed << sprecision(15) << r << endl;
当然,有些系统的RAND_MAX要小得多,在这种情况下,结果可能不那么"精确"——但是,你仍然应该得到 9-12 范围内的数字,只是它们更有可能是"相同的"。
为什么不从随机函数的多次调用中创建你的值呢?
例如:
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;
我个人会尝试兰德函数的新实现,或者至少乘以当前时间或其他东西。
就我而言,我使用的是 MQL5,这是特定市场的非常接近的C++导数,其唯一的随机生成器生成从 0 到 32767 (= (2^15(-1( 的随机整数。精度太低了。
所以我调整了他的想法——随机生成一串我想要的任何长度的数字——来解决我的问题,比我能找到或想到的任何其他东西都更可靠(也可以说更随机(。我的版本构建了一个字符串并在最后将其转换为双精度 - 避免了任何潜在的数学/舍入错误(因为我们都知道0.1 + 0.2 != 0.3
(
将其发布在这里,以防对任何人有帮助。
(免责声明:以下内容是有效的MQL5。MQL5 和 C++ 非常接近,但有一些差异。 例如。没有RAND_MAX常量(所以我对 32767 进行了硬编码(。 我不完全确定所有差异,因此这里可能存在C++语法错误。请相应地调整(。
const int RAND_MAX_INCL = 32767;
const int RAND_MAX_EXCL = RAND_MAX_INCL + 1;
int iRandomDigit() {
const double dRand = rand()/RAND_MAX_EXCL; // double 0.0 <= dRand < 1.0
return (int)(dRand * 10); // int 0 <= result < 10
};
double dRandom0IncTo1Exc(const int iPrecisionDigits) {
int iPrecisionDigits2 = iPrecisionDigits;
if ( iPrecisionDigits > DBL_DIG ) { // DBL_DIG == "Number of significant decimal digits for double type"
Print("WARNING: Can't generate random number with precision > ", DBL_DIG, ". Adjusted precision to ", DBL_DIG, " accordingly.");
iPrecisionDigits2 = DBL_DIG;
};
string sDigits = "";
for (int i = 0; i < iPrecisionDigits2; i++) {
sDigits += (string)iRandomDigit();
};
const string sResult = "0." + sDigits;
const double dResult = StringToDouble(sResult);
return dResult;
}
<小时 />在对@MasterPlanMan答案的评论中指出 - 其他答案使用为该问题设计的更"官方"方法,来自标准库等。 但是,我认为从概念上讲,当面临其他答案无法解决的限制时,这是一个很好的解决方案。
- 如何防止 c++ 在从浮点型转换为双精度型(不适用于 IO)时添加额外的小数?
- 正在将csv文件读取为双精度矢量
- 我可以信任表示整数的浮点或双精度来保持精度吗
- 如何在C++中的同一函数中使用字符串和双精度
- 特征::矩阵<双精度,1,3> 结构类型函数中的返回类型函数
- 检查是否以特定精度给出双精度
- 转换函数,将 std::数组的双精度作为参数或双精度作为参数单独转换
- C 字符串返回字符串的整数/双精度/长整型值
- 为什么将双精度转换为 int 似乎在第 16 位数字之后将其四舍五入?
- 如何使双精度值的 C++ 和 C# 中的结果相同
- 使用浮点数和双精度数的非常小数字的数学
- 如何使用按位运算将随机uint64_t转换为范围 (0, 1) 的随机双精度
- 如何随机化双精度/浮点数据类型? C++
- 如何在 c++ 中生成介于 0 和变量之间的随机双精度
- C++:高精度随机双精度数
- 如何在C++中以高精度生成随机双精度数
- 在不同范围内生成随机双精度
- 生成随机整型和双精度的c++模板类
- 在一系列值之间生成随机双精度
- 在 POSIX 上产生随机双精度的最佳方法是什么?