백준 13301 타일 장식물 문제를 파이썬으로 풀었다.
#13301
N = int(input())
a,b = 0,1
for i in range(N):
a,b = b,a+b
print(2*(a+b))
똑같은 방법으로 자바스크립트로 풀었다.
// 13301 틀린코드
const readline = require("readline");
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
rl.on("line", (input) => {
const N = parseInt(input);
let a = 0;
let b = 1;
for (let index = 0; index < N; index++) {
temp = a;
a = b;
b = temp + a;
}
console.log(2 * (a + b));
rl.close();
});
결과를 확인해보니 N이 79일때와 80일때 답이 달랐다.
숫자가 너무 커서 그런것 같았다.
자바스크립트에서 숫자 연산을 수행할 때, 정확성과 정밀도에 관련된 몇 가지 주의 사항이 있을 수 있습니다. 이는 모든 프로그래밍 언어에서 발생하는 일반적인 문제입니다.
숫자의 정밀도 문제는 대개 부동 소수점 산술에 관련되어 있습니다. 부동 소수점은 실수를 근사적으로 표현하기 위해 사용되며, 표현 범위와 정밀도에 제한이 있을 수 있습니다. 이로 인해 매우 큰 숫자나 매우 작은 숫자의 경우 부정확한 결과가 발생할 수 있습니다.
찾아보니 BigInt라는 내장 객체가 있었다.
BigInt 는 Number 원시 값이 안정적으로 나타낼 수 있는 최대치인 2^53 - 1보다 큰 정수를 표현할 수 있는 내장 객체입니다.
BigInt는 정수 리터럴의 뒤에 n을 붙이거나(10n) 함수 BigInt()를 호출해 생성할 수 있습니다.
BigInt와 Number는 어떤 면에서 비슷하지만 중요한 차이점이 있습니다. 예컨대 BigInt는 내장 Math 객체의 메서드와 함께 사용할 수 없고, 연산에서 Number와 혼합해 사용할 수 없습니다. 따라서 먼저 같은 자료형으로 변환해야 합니다. 그러나, BigInt가 Number로 바뀌면 정확성을 잃을 수 있으니 주의해야 합니다.
...
// BigInt() 객체 생성
let a = BigInt(0);
let b = BigInt(1);
let temp = BigInt(0);
...
const answer = 2n * (a + b); // 그냥 곱하기 2가 아니라 2를 빅인트로(2n) 만들어야 계산가능
...
TypeError: Cannot mix BigInt and other types, use explicit conversions
console.log("answer:", answer);
//answer: 122611581443223182n
console.log("Number(answer):", Number(answer));
// Number(answer): 122611581443223180
console.log("answer.toString():", answer.toString());
// answer.toString(): 122611581443223182
const readline = require("readline");
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
rl.on("line", (input) => {
const N = parseInt(input);
let a = BigInt(0);
let b = BigInt(1);
let temp = BigInt(0);
for (let index = 0; index < N; index++) {
temp = a;
a = b;
b = temp + a;
}
const answer = 2n * (a + b);
console.log(answer.toString());
rl.close();
});