2017-05-07 1 views
2

를 들어, 1 N> 17를 반환하지만 내가 17보다 큰 숫자 입력, 나는 항상 나가 1계승 기능은 I 전자를 계산할 수 있도록 내가 계승을위한 자바의 기능을 썼다 겉으로는 아무 이유없이

이 함수이다

public int fact(int n) { 
    for(int i = n-1; i > 1; i--) { 
     n *= i; 
    } 
    if(n <= 0) { 
     n = 1; 
    } 
    return n; 
} 
+4

https://en.wikipedia.org/wiki/Integer_overflow – Nayuki

+1

Java에서 int의 최대 값을 확인하십시오. Factorial은 17보다 길다. 그래서 이것이 "음수"가되고 두 ​​번째 if 문이 1 –

답변

3

int 유형 최대치 갖는다 (2^32 - 미만이다 fact(13) 1). 이 값을 초과하면 숫자 연산자의 결과가 오버플로되어 잘못된 결과가 나타납니다. int 대신 long을 사용하면 코드가 n의 (약간) 높은 값으로 작동 할 수 있습니다. 17!Integer 데이터 타입에 저장할 수있는 매우 큰 값이기 때문에

+1

이되어'BigInteger'를 사용하여 n의 모든 값에 대해 문제를 해결하겠습니까? –

+0

@Shashwat'BigInteger'는 자체 한계가 있지만'long'보다 훨씬 큽니다. – Eran

+0

@Eran은 계승의'BigInteger' 버전을 추가했습니다. –

3

그것은 그리고 당신이 그것을 저장하려고하면, 그것은 n 다음 n 부정적인 1에 의해 다시 도착하게되면 잘못된 result.So 발생할 수 있습니다 Integer에서 오버 플로우가 발생합니다 그리고 당신은 그것을 돌려 보낼 것입니다, 그래서 1을 얻을 것입니다.

Overflow을 피하기 위해 Long을 사용하십시오. 최대 값은 2^63-1입니다. 값보다 큰 값을 사용하려면 BigInteger을 사용하십시오.

+1

에는 계승의 'BigInteger'버전이 추가되었습니다. –

0

팩토리얼의 BigInteger 버전.

public static BigInteger factorial(BigInteger n) { 
    BigInteger factorial = BigInteger.valueOf(1); 

    for (int i = 1; i <= n.intValue(); i++) { 
     factorial = factorial.multiply(BigInteger.valueOf(i)); 
    } 

    return factorial; 
} 

는 효율적인 계승 구현에이 post 살펴 있다고 가정하자.

+1

'return (n <= 0)? BigInteger.ZERO : IntStream.rangeClosed (2, n) .mapToObj (BigInteger :: valueOf) .reduce (BigInteger.ONE, (a, b) -> a.multiply (b)); –

관련 문제