매우 큰 수 혹은 매우 정밀한 수
개정판에는 1판에 수록되지 않은 소소한 추가 내용이 있습니다. 분량은 많지 않지만, 필요할 때 요긴하게 활용할 수 있습니다.
Inf
이론적으로 연산이 가능하지만 R에서 다루기에 너무 크거나 작은 수의 경우 Inf
또는 -Inf
가 된다. 예를 들어, 현재 내 컴퓨터에서 1.32e+308
( \(1.32\times 10^{308}\) )은 괜찮지만, 이 값에 10을 곱한 1.32e+309
는 R의 기본적인 수치형 데이터 타입으로는 감당할 수 없고, Inf
이 된다.
1.32e+308
## [1] 1.32e+308
1.32e+308*10
## [1] Inf
주석
여기까지는 1판도 동일하지만, 개정판에는 주석을 달았습니다.
매우 큰 정수를 다루고자 한다면 gmp
패키지를 사용할 수 있다.
132*10^306
132*10^306*10
library(gmp)
132*as.bigz(10)^306
132*as.bigz(10)^306*10
## [1] 1.32e+308 ## [1] Inf ## Big Integer ('bigz') : ## [1] 132000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 ## Big Integer ('bigz') : ## [1] 1320000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
정밀도 높은 실수를 원한다면 Rmpfr
패키지를 사용할 수 있다.
library(Rmpfr)
1.32*mpfr(10, precBits=200)^308
1.32*mpfr(10, precBits=1000)^308*10
## 1 'mpfr' number of precision 200 bits ## [1] 132000000000000006217248937900876626372337341308593750000000069173768144116117516289328928688999232392263594354818986881548131428321966147378197417917623438640731906955126541300338295222086598925664490315642274078852508498640231647700583887120935905281397393124432109801611236868030392460322828141509553946624 ## 1 'mpfr' number of precision 1000 bits ## [1] 1320000000000000062172489379008766263723373413085937500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
다른 예를 보자.
print(1/pi, digits=18)
## [1] 0.31830988618379069
print(1/pi, digits=30)
## Error in print.default(1/pi, digits = 30): invalid 'digits' argument
print(mpfr(1, precBits=1000)/pi, digits=30)
## 1 'mpfr' number of precision 1000 bits ## [1] 0.318309886183790683946033850086
아무리 유효숫자가 많아도 초월수인 \(1/\pi\) 를 정확하게 나타낼 순 없지만 정밀도를 precBits=
로 조절할 수 있다.
번외
\(\log(1+x)\) 를 생각해보자. 이 함수는 \(x\) 가 0과 매우 가까울 때, \(\log(1+x) \approx x\) 이다.
curve(log(1+x), xlim=c(0,1))
abline(a=0, b=1, lty='dotted')
curve(log(1+x), xlim=c(0,0.2))
abline(a=0, b=1, lty='dotted')
R에서의 계산 결과는 \(x \approx 0\) 일때, Underflow가 일어나 \(0\) 이 되고 만다.
log(1+1e-16)
## [1] 0
다음은 이를 방지하는 두 방법을 보여준다. 보통은 log1p
함수를 써서 \(\log(1+x)\) 를 구한다.
log(mpfr(1, precBits=100)+1e-16)
## 1 'mpfr' number of precision 100 bits ## [1] 9.999999999999925335268002770493e-17
log1p(1e-16)
## [1] 1e-16
Leave a comment