факторный метод не работает!

Привет, это метод факториала, но он печатает 0 в консоли, пожалуйста, помогите мне, спасибо

public class Demo {

    public static void main(String[] args) {
        Demo obj = new Demo();
        System.out.println(obj.factorial(500));
    }

    public int factorial(int n) {
        int fact = 1;

        for (int i = 2; i <= n; i++) {
            fact= fact*i;
        }
        return fact;
    }

EDITED: вернет Бесконечность!

public class Demo {

    public static void main(String[] args) {
        Demo obj = new Demo();
        System.out.println(obj.factorial(500));
    }

    public double  factorial(long n) {
       double fact = 1;

        for (int i = 2; i <= n; i++) {
            fact= fact*i;
        }
        return fact;
    }
}

person user472221    schedule 11.10.2010    source источник
comment
Используйте BigInteger человек! Знай свой язык в первую очередь. \м/   -  person ivorykoder    schedule 11.10.2010


Ответы (6)


Поскольку 500! равно 1220136825991110068701238785423046926253574342803192842192413588385845373153881997605496447502203281863013616477148203584163378722078177200480785205159329285477907571939330603772960859086270429174547882424912726344305670173270769461062802310452644218878789465754777149863494367781037644274033827365397471386477878495438489595537537990423241061271326984327745715546309977202781014561081188373709531016356324432987029563896628911658974769572087926928871281780070265174507768410719624390394322536422605234945850129918571501248706961568141625359056693423813008856249246891564126775654481886506593847951775360894005745238940335798476363944905313062323749066445048824665075946735862074637925184200459369692981022263971952597190945217823331756934581508552332820762820023402626907898342451712006207714640979456116127629145951237229913340169552363850942885592018727433795173014586357570828355780158735432768888680120399882384702151467605445407663535984174430480128938313896881639487469658817504506926365338175055478128640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000, вы не можете вписать его в int (которое колеблется до 2147483647).

  • Используя int, вы можете хранить только до 12!.
  • Используя long, вы получите до 20!
  • Используя double, вы получите до 170!.

Вот решение с использованием BigInteger:

public static BigInteger factorial(int i) {
    BigInteger n = BigInteger.valueOf(i);
    while (--i > 0)
        n = n.multiply(BigInteger.valueOf(i));
    return n;
}
person aioobe    schedule 11.10.2010
comment
Большое спасибо за ответ! :) - person user472221; 11.10.2010
comment
Чтобы повысить производительность, вы также можете сначала проверить i и при необходимости переключиться на BigInteger ^^! - person helpermethod; 11.10.2010
comment
Это было бы незначительным улучшением, поскольку оно оптимизирует метод только для действительно небольших входных значений. - person aioobe; 11.10.2010

Вы никак не сможете установить 500! на 32-битную int.

Для вычислений с большими числами рассмотрите возможность использования double или BigInteger, в зависимости от того, хотите ли вы приблизительный или точный ответ.

(На самом деле, для 500! даже double будет недостаточно: Double.MAX_VALUE равно 1,7976931348623157E+308, что «только» позволит вам подняться до 170!)

person Grodriguez    schedule 11.10.2010

Есть две вещи, на которые вы должны обратить внимание, если вам нужно вычислить факториальную функцию:

1) Запоминание. Это значительно ускорит ваши вычисления, так как функция факториала имеет рекурсивное определение. Что вы делаете, так это кэшируете предыдущие вычисления, поэтому, когда вы запрашиваете k!, вы можете получить его за один шаг, вычислив k*((k-1)!), если у вас есть (k-1)! в кэше.

2) приближение Стирлинга. Если вам нужно вычислить большие факториалы, вы можете очень быстро аппроксимировать их таким образом и с гарантированными пределами ошибки, чтобы вы могли сказать, будет ли аппроксимация приемлемо близкой для вашего приложения.

Если вы не сделаете ни того, ни другого, вы обнаружите, что есть относительно небольшие k, для которых вы просто не можете вычислить k! за разумное время.

person uckelman    schedule 11.10.2010

Гродригес прав - это почти наверняка вызвано целочисленным переполнением.

Если вы протестируете свой метод с более скромными входными данными, он, похоже, вернет правильный результат:

public static void main(String[] args) {
   Demo obj = new Demo();
   for (int i = 0; i < 10; i++)
      System.out.println(i + "! = " + obj.factorial(i));
} 

500! огромный; при тестировании вашей функции разумно начинать с меньших входных данных.

person Andrzej Doyle    schedule 11.10.2010

500! намного слишком велик, чтобы вместить long или double.
Чтобы получить это, вам придется использовать другие методы.

Но сначала какой программе нужен 500!?

person Nivas    schedule 11.10.2010
comment
какой программе нужно 500!? Задачи комбинаторики часто имеют безумно большие числа. - person Tony Ennis; 11.10.2010
comment
@ Тони, я собирался сказать ОП, что у него 500! вероятно не имеет отношения к его делу. Возможно, плохо сформулировано. - person Nivas; 11.10.2010

Есть очень хорошая оптимизация для реализации факторизации: см., например, luschny.de за хорошую реализацию их на Java. Некоторым требуется больше математических знаний, чем другим... Получайте удовольствие от библиотеки :-)

person Dave    schedule 11.10.2010