출처
백준 온라인 저지
https://www.acmicpc.net/problem/2748
2748번: 피보나치 수 2
피보나치 수는 0과 1로 시작한다. 0번째 피보나치 수는 0이고, 1번째 피보나치 수는 1이다. 그 다음 2번째 부터는 바로 앞 두 피보나치 수의 합이 된다. 이를 식으로 써보면 Fn = Fn-1 + Fn-2 (n ≥ 2)가
www.acmicpc.net
문제
피보나치 수는 0과 1로 시작한다. 0번째 피보나치 수는 0이고, 1번째 피보나치 수는 1이다. 그다음 2번째부터는 바로 앞 두 피보나치 수의 합이 된다.
이를 식으로 써보면 Fn = Fn-1 + Fn-2 (n ≥ 2)가 된다.
n=17일 때까지 피보나치 수를 써보면 다음과 같다.
0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597
n이 주어졌을 때, n번째 피보나치 수를 구하는 프로그램을 작성하시오.
풀이
1003번의 피보나치 함수 문제를 해결했다면 이 문제도 쉽게 해결할 수 있을 것 같았지만, 생각하지 못했던 문제가 존재했습니다.
90 피보나치 수는 '2,880,067,194,370,816,000'의 엄청 큰 수입니다.
하지만 javascript에 존재하는 한계점으로 인해 정확한 수를 표시할 수 없었습니다.
그러므로 '2,880,067,194,370,816,000' 범위를 넘은 값을 나타낼 수 있는 객체가 필요하게 됩니다.
그리고 그 해답은 ' BigInt ' 객체였습니다.
DP의 값들을 BigInt 객체 형식으로 바꾸어 피보나치 수를 계산해주고 마지막 출력 단계에서 BigInt의 값을 진수로 표현시켜주는 내장 toString 메서드를 사용하여 반환시켜줍니다.
코드
const n = require('fs').readFileSync('/dev/stdin').toString() * 1;
const DP = [0, 1];
for (let i = 1; i < n; i++) {
DP[i+1] = BigInt(DP[i]) + BigInt(DP[i-1]);
}
console.log(DP[n].toString());
다른 코드
1003번 문제에서 사용했던 이전 값만을 계속 바꿔주어 누적시키는 방법을 사용했고 이 방법 또한 BigInt 객체를 사용하였습니다.
const len = require('fs').readFileSync('/dev/stdin').toString() * 1;
let prevN = 1, n = 0;
for (let i = 0; i < len; i++) {
const tmpPrevN = BigInt(n);
n = tmpPrevN + BigInt(prevN);
prevN = tmpPrevN;
}
console.log(n.toString());
참고 사이트
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/BigInt
BigInt - JavaScript | MDN
BigInt는 Number 원시 값이 안정적으로 나타낼 수 있는 최대치인 2^53 - 1보다 큰 정수를 표현할 수 있는 내장 객체입니다.
developer.mozilla.org
[JS] 아주 큰 숫자 한계 처리
문제점 자바스크립트의 기본 자료형의 수는 한계점이 존재합니다. Number.MAX_SAFE_INTEGER의 값보다 큰 값은 정확하지 않을 때가 많습니다. 해결방법 BigInt 타입의 값을 만들어 계산하는 방법으로 해
gurtn.tistory.com