简体   繁体   中英

Floating point exception in C

#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]);
  }
}

When I compile it returns "Floating point exception (core dumped)", not sure why. (Have tried converting all the probs with (double).) Any ideas?

fctl(52) is waaaaay too big for an int . You're going to have to rethink your approach to doing this calculation. You can output INT_MAX to see how far you can actually go. You can buy a tiny bit more space by using unsigned long long (cf. ULLONG_MAX ) but that is still nowhere near big enough for 52! .

Invoking integer overflow causes undefined behaviour; "floating point exception" often means attempt to do integer division by zero, which is plausible given your attempted calculations plus the fact that they overflowed. Don't ask me why this is reported as FPE despite the fact that it didn't involve any floating point. (probably "historical reasons")

After accept answer.

@Matt McNabb wells points out that fctl(52) is certianly to big for a vaid numeric result to fit in an long . (@mrVoid asserts 225 bit int needed.)

But certain @Lưu Vĩnh Phúc is on the right track as to what caused the exception.

fctl(x) will be the product of numbers 1 to x , half of those are even. Thus fctl(x) will have x/2 LSbits set to zero.

Assuming 32-bit int , once the number of LSBits of fctl(nr) and fctl(r) exceed/meet 32, the product (fctl(nr)*fctl(r)) will be 0 and return fctl(n) / (0); throws an exception.

On many systems an integer divide by 0 is reported as an floating-point error. I think this oddity occurs to simplify trap handling.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM