#include <stdio.h>
#include <math.h>
#include <string.h>
long fctl(int n){
int a=1,i;
for(i=n;i>1;--i)
a*=i;
return a;
}
long ch(int n, int r){
return fctl(n) / (fctl(n-r)*fctl(r));
}
int main(){
char *hands[] = {"onepair", "twopair", "triple", "straight", "flush", "fullhouse", "fourofakind", "straightflush", "royalflush"};
double handprobs[9];
handprobs[0] = ch(13,1)*ch(4,2) * ch(12,3)*pow(ch(4,1), 3) / ch(52,5);
handprobs[1] = ch(13,2)*pow(ch(4,2), 2) * ch(11,1)*ch(4,1) / ch(52,5);
handprobs[2] = ch(13,1)*ch(4,3) * ch(12,2)*pow(ch(4,1), 2) / ch(52,5);
handprobs[3] = 10.0 * pow(ch(4, 1),5) / ch(52, 5) - 10.0/ch(52,5) - 4.0/ch(52,5);
handprobs[4] = ch(13,5)*ch(4,1) / ch(52, 5) - 10.0/ch(52,5);
handprobs[5] = ch(13,1)*ch(4,3) * ch(12,1)*ch(4,2) / ch(52,5);
handprobs[6] = ch(13,1)*1 * ch(12,1)*ch(4,1) / ch(52,5);
handprobs[7] = 40.0 / ch(52, 5) - 4.0/ch(52,5),
handprobs[8] = 4.0 / ch(52, 5);
int i;
for(i=0;hands[i];++i){
printf("%s\t%f\n",hands[i], handprobs[i]);
}
}
当我编译它时返回&#34;浮点异常(核心转储)&#34;,不知道为什么。 (尝试用(双)转换所有的probs。)任何想法?
答案 0 :(得分:1)
fctl(52)
对int
来说太大了。您将不得不重新考虑进行此计算的方法。您可以输出INT_MAX
以查看实际可以走多远。您可以使用unsigned long long
(参见ULLONG_MAX
)购买更多空间,但对于52!
来说,这仍然不够大。
调用整数溢出会导致未定义的行为; &#34;浮点异常&#34;通常意味着尝试将整数除以零,这在您尝试的计算加上它们溢出的事实时是合理的。不要问我为什么这被报告为FPE,尽管事实上它并没有涉及任何浮动点。 (可能&#34;历史原因&#34;)
答案 1 :(得分:1)
接受回答后。
@Matt McNabb井指出,fctl(52)
对于适合long
的虚拟数值结果而言非常重要。 (@mrVoid断言需要225位int
。)
但某些@LưuVĩnhPhúc正在走上正确轨道,以了解导致例外的原因。
fctl(x)
将是数字1
到x
的乘积,其中一半是偶数。因此fctl(x)
将x/2
个LSbits设置为零。
假设32位int
,一旦fctl(n-r)
和fctl(r)
的LSBits数超过/满足32,产品(fctl(n-r)*fctl(r))
将为0且return fctl(n) / (0);
抛出异常。
在许多系统上,整数除以0被报告为浮点错误。我认为这种奇怪的现象是为了简化陷阱处理。