Почему я получаю исключение с плавающей запятой - PullRequest
0 голосов
/ 29 сентября 2019

Я не думаю, что в моем коде есть какая-либо точка, я достигаю нуля или делю ее на ноль, поэтому кто-нибудь может мне помочь, почему я получаю исключение с плавающей запятой для ввода 20 75

Я просто вычисляюфакториал для 2 * n -1 и погружение с факториалом n и n-1, но я не знаю, где мой код получает ноль или что-то еще является причиной

int fact(int num) {
    if(num == 1 || num == 0) return 1;
    else return (num*fact(num-1));
}
int Solution::solve(int A) {
    int val1 = fact(A-1);
    int val2 = fact(A-1+A-1);
    int ans = (val2/((val1*val1)%1000000007))%1000000007;
    return (ans/A)%1000000007;
}

для A = 20 или A= 75 Я получаю исключение с плавающей запятой

Ответы [ 2 ]

1 голос
/ 29 сентября 2019

При вводе A = 20 вы вызываете fact(20 - 1) и fact(20 - 1 + 20 - 1), которые fact(19) fact(38).Факториал 19 равен 121645100408832000, а факториал 38 равен 523022617466601111760007224100074291200000000.

На типичном ПК наибольшее представимое значение для int равно 2147483647, что меньше любого из вышеуказанных факториалов, которые вы пытаетесь вычислить.Ваша программа переполняет целое число со знаком, и поведение программы не определено.

Я не думаю, что в моем коде есть какая-то точка, я ... делю ее на ноль

(val1*val1)%1000000007 может быть нулем для некоторых значений val1.Поэтому val2/((val1*val1)%1000000007) может делиться на ноль.Простой случай, когда это имеет место, когда val1 равен нулю, а другой случай, когда это 1000000007. Возможно, вы думаете, что val1 никогда не может быть ни одним из этих значений, поскольку они не являются факториалами, но это может быть полностьюлюбое значение, если вы перепрограммировали подпись в вашей программе.

Наибольшее факториальное представление, представляемое как 32-битное целое число, равно 12!и, следовательно, самый большой вход, который может решить ваша функция - это A = 7.

0 голосов
/ 29 сентября 2019

Я не могу добавить много, но если вы измените все int var = ... переменные на long long int var = ... (хотя я думаю, что long long int не рекомендуется использовать согласно Руководству по стилю Google), это будет работать и с вводом20 из-за причин, упомянутых в предыдущих комментариях:

long long int fact(long long int num) {
    if(num == 1 || num == 0) return 1;
    else return (num*fact(num-1));
}
int Solution::solve(int A) {
    long long int val1 = fact(A-1);
    long long int val2 = fact(A-1+A-1);
    long long int ans = (val2/((val1*val1)%1000000007))%1000000007;
    return (ans/A)%1000000007;
}
...