2012-03-15 2 views
4

Я использую эту факторную программу для Java:Факториал в Java

public static long factorial(int a) { 

    if(a<1) { 
     return 1; 
    } 
    long result=1; 
    long x=a; 
    while(x>1) { 
     result*=x;      
     x--; 
    } 
    return result; 
} 

Тем не менее, кажется, «перерыв» и возвращает отрицательное число после факториала 25. Она возвращает отрицательное число для а затем просто возвращает «0».

Я делаю что-то неправильно, что вызывает это?

+3

Знаете ли вы что-нибудь о самом большом количестве и междунар может держать, и это ваша домашняя работа? –

+0

Это не моя домашняя работа, это моя забавная работа :) (я выродка). Я бы никогда не просил о помощи, как это для моей домашней работы. Я ничего не знаю о самом большом количестве, которое может удерживать int. Я посмотрю это в документах. – Toby

+0

@ dann.dev: Что такое 'int'? – SLaks

ответ

7

Вы переполнены long.
Вместо этого используйте BigInteger.

+1

Да: http://membres.multimania.fr/rsirdey/facttabl.htm – duffymo

+0

Хорошая страница, заставляет меня головокружение через некоторое время! –

+0

У меня возникли проблемы с использованием BigIntegers, я бы перевел долгое время на BigInteger прямо перед возвращением? – Toby

3

25! больше, чем Long.MAX_VALUE ...

0

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

http://www.iro.umontreal.ca/~simardr/ssj/doc/html/umontreal/iro/lecuyer/util/Num.html

Если вы должны сохраняться в использовании этой реализации, я рекомендую посмотреть в запоминание. Зачем перечитывать значения? После того, как у вас есть один, держитесь за него и просто раздавайте его на повторных запросах.

+0

Это не поможет; он все равно будет переполняться. – SLaks

+0

В конце концов, но двойной будет висеть там намного дольше, чем долгая воля. И естественный журнал также задержит его. Полезно для комбинаторных вычислений: просто добавляйте и вычитайте натуральные журналы. – duffymo

4

25! = 15511210043330985984000000

Максимальное значение долго в Java является 2^63-1 = 9223372036854775807 (source).

25! составляет около 1.7 * 10^6, размер наибольшего значения, который может хранить long в Java. Вместо этого используйте BigInteger.

0

Заканчивать http://en.wikipedia.org/wiki/Integer_overflow, я знаю, что название относится к целому, но принцип означает межд, длинные, двойные и т.д.

Короче говоря, примитивный тип данных имеет максимальное значение, когда вы идете на это, его обертывает и запускается снова. если вы действительно хотите, чтобы его обманули, узнайте о двоичном дополнении, чтобы полностью его понять.

1

Overflow (и underflow) является тихим в соответствии с JLS, поэтому ваш результат был «неожиданностью».

У вас есть два варианта:

  • если требуется точный ответ, используйте BigInteger
  • если точность не требуется, используйте double (хотя и это будет переливаться мимо 170!)
0

Вот что вам не хватает: когда подписанный целочисленный примитивный тип (такой как short, int, long) получает приращение выше значащего значения, которое он может представлять, он пытается перевернуть свой битовый знак, который является самым левым битом, который является только предполагать d для обозначения знака числа. 1 в бите знака указывает отрицательное значение. Это явление называется целым переполнением.

Рассмотрите вымышленный трехбитовый тип данных с примитивным знаком (для сравнения длина Java составляет 64 бита). Он может представлять числа от -4 до 3.

3, самое большое положительное значение в 3-х битное число может представлять собой, выглядит следующим образом: 011

добавить 1 к 011, и вы получите: 100 (число часть перетекает в знаковой части)

десятичная версия 100 равна -4

Однако, когда вы сталкиваетесь с длительностью долготы, есть много цифр для подсчета, так что вот быстрый способ определить наибольшее число, определенное данным неубывающим (в данном случае факториал):

long n = 1; 
while (factorial(n) > 0) { 
    System.out.println("factorial of " + n++ + " can fit in a long!"); 
} 

Похоже, что это должен быть бесконечный цикл, но это не так; в конечном счете, factorial (n) будет возвращать отрицательный результат из-за переполнения целых чисел. Это даст вам следующий вывод:

factorial of 1 can fit in a long! 
factorial of 2 can fit in a long! 
factorial of 3 can fit in a long! 
factorial of 4 can fit in a long! 
factorial of 5 can fit in a long! 
factorial of 6 can fit in a long! 
factorial of 7 can fit in a long! 
factorial of 8 can fit in a long! 
factorial of 9 can fit in a long! 
factorial of 10 can fit in a long! 
factorial of 11 can fit in a long! 
factorial of 12 can fit in a long! 
factorial of 13 can fit in a long! 
factorial of 14 can fit in a long! 
factorial of 15 can fit in a long! 
factorial of 16 can fit in a long! 
factorial of 17 can fit in a long! 
factorial of 18 can fit in a long! 
factorial of 19 can fit in a long! 
factorial of 20 can fit in a long!