C++ 计算概率C++;伯努利审判
程序要求用户输入抛硬币的次数(n;试验次数) 成功被认为是成功的象征 程序完美地创建了一个介于0和1之间的随机数。0被认为是头和成功 然后,程序应该输出获得x个头部数量的期望值。例如,如果硬币被翻转了4次,那么使用该公式,下列概率是多少C++ 计算概率C++;伯努利审判,c++,combinations,probability,factorial,C++,Combinations,Probability,Factorial,程序要求用户输入抛硬币的次数(n;试验次数) 成功被认为是成功的象征 程序完美地创建了一个介于0和1之间的随机数。0被认为是头和成功 然后,程序应该输出获得x个头部数量的期望值。例如,如果硬币被翻转了4次,那么使用该公式,下列概率是多少 nCk * p^k * (1-p)^(n-k) Expected 0 heads with n flips: xxx Expected 1 heads with n flips: xxx ... Expected n heads with n flips: xx
nCk * p^k * (1-p)^(n-k)
Expected 0 heads with n flips: xxx
Expected 1 heads with n flips: xxx
...
Expected n heads with n flips: xxx
当使用“较大”的数字进行此操作时,这些数字会出现奇怪的值。如果在输入中输入15或20,则会发生这种情况。我得到了0和负的值,这个值应该是xxx
在调试过程中,我注意到nCk为负值,并且对上限值不正确,我相信这就是问题所在。我使用以下公式进行组合:
double combo = fact(n)/fact(r)/fact(n-r);
以下是my fact函数的伪代码:
long fact(int x)
{
int e; // local counter
factor = 1;
for (e = x; e != 0; e--)
{
factor = factor * e;
}
return factor;
}
有什么想法吗?我的猜测是我的阶乘或组合函数超出了最大值或其他值。您没有提到如何声明
因子。我认为您正在得到整数溢出。我建议你用双人的。这是因为,因为您正在计算期望值和概率,所以不应该太在意精度
尝试将事实函数更改为
double fact(double x)
{
int e; // local counter
double factor = 1;
for (e = x; e != 0; e--)
{
factor = factor * e;
}
return factor;
}
编辑:
同样要计算nCk,您不需要计算3次阶乘。您可以用以下方法简单地计算该值
if k > n/2, k = n-k.
n(n-1)(n-2)...(n-k+1)
nCk = -----------------------
factorial(k)
您超过了长时间的最大值。阶乘增长如此之快,以至于您需要正确的数字类型——它的类型取决于您需要的值
Long是一个有符号整数,一旦通过2^31,该值将变为负数(使用2的补码数学)
使用未签名的long将为您赢得一点时间(多一点),但对于factorial,这可能不值得。如果您的编译器支持long-long,请尝试使用“unsignedlong-long”。这将(通常取决于编译器和CPU)使您使用的位数增加一倍
您也可以尝试切换到使用double。你将面临的问题是,随着数字的增加,你将失去准确性。double是一个浮点数,因此您将有固定数量的有效数字。如果您的最终结果是近似值,那么这可能行得通,但如果您需要精确的值,它就行不通
如果这些解决方案都不适用于您,您可能需要求助于使用“无限精度”数学包,您应该能够搜索它。你没有说你是用C还是C++;这将是一个更愉快的C++,因为它将提供一个类,它像一个数字,并使用标准算术运算符。尝试将事实函数的类型更改为double,并查看是否接受更高的值。以下是如何在溢出危险最小的情况下计算nCk
,如果确实发生溢出,则不会以静默方式进行。