반응형
"""
calculate
50000
/ n \
| 10 - 1 |
| ------------ |
| n |
\ 10 /
"""
import math
def f(n):
return ((10 ** n - 1) / (10 ** n)) ** 50000
def f2(n):
return (1 - 10 ** (-n)) ** 50000
def f_exp10_log10(n):
exponent = 50000 * (math.log10(10 ** n - 1) - n)
return 10 ** exponent
def f_exp2_log2(n):
exponent = 50000 * (math.log2(10 ** n - 1) - n * math.log2(10))
return 2 ** exponent
def f_exp_ln(n):
exponent = 50000 * (math.log(10 ** n - 1) - n * math.log(10))
return math.e ** exponent
for n in range(1, 20):
r = f(n), f2(n), f_exp10_log10(n), f_exp2_log2(n), f_exp_ln(n)
print(n, r)
1에 가깝지만, 1보다 작은 수를 여러번 거듭제곱한 결과를 계산하는 코드입니다. 수치계산에는 오차가 있기 때문에, 여러 방법으로 구현을 해 보고 결과를 봤습니다.
1 (0.0, 0.0, 0.0, 0.0, 0.0)
2 (5.750821364590612e-219, 5.750821364590612e-219, 5.750821364582722e-219, 5.750821364628167e-219, 5.750821364428947e-219)
3 (1.8810974691235773e-22, 1.8810974691235773e-22, 1.8810974691317268e-22, 1.8810974691862467e-22, 1.8810974690998245e-22)
4 (0.006736262610603238, 0.006736262610603238, 0.006736262610461906, 0.006736262610695879, 0.006736262610337693)
5 (0.6065291433791509, 0.6065291433791509, 0.6065291433740616, 0.6065291433487209, 0.6065291433184291)
6 (0.9512294007185952, 0.9512294007185952, 0.9512294007397432, 0.951229400728889, 0.9512294006267303)
7 (0.9950124789465479, 0.9950124789465479, 0.99501247895579, 0.9950124789848356, 0.9950124789577935)
8 (0.9995001249741594, 0.9995001249741594, 0.9995001249962548, 0.9995001250444372, 0.9995001249378198)
9 (0.9999500012513682, 0.9999500012513682, 0.9999500012619135, 0.9999500013180697, 0.9999500010682155)
10 (0.9999950000120861, 0.9999950000120861, 0.9999949999318897, 0.9999950000439347, 0.9999949997456341)
11 (0.9999995000000836, 0.9999995000000836, 0.9999994999716129, 0.9999995001017706, 0.9999994999556747)
12 (0.9999999500011073, 0.9999999500011073, 0.9999999500994053, 0.9999999500101658, 0.9999999499067384)
13 (0.9999999949984453, 0.9999999949984453, 0.9999999950917446, 0.9999999950748931, 0.9999999948485652)
14 (0.9999999995003996, 0.9999999995003996, 0.9999999995909787, 0.9999999995074893, 0.9999999992894573)
15 (0.99999999995004, 0.99999999995004, 1.0, 1.0, 0.9999999996447286)
16 (0.9999999999944489, 0.9999999999944489, 1.0, 1.0, 1.0)
17 (1.0, 1.0, 1.0, 1.0, 1.0)
18 (1.0, 1.0, 1.0, 1.0000000002462552, 0.9999999996447286)
19 (1.0, 1.0, 1.0, 1.0000000002462552, 1.0)
- n 이 1, 2, 3 까지는 모든 구현의 결과가 같아 보이고,
- n 이 15일 때, 1이라는 결과 (수학적으로는 도달하지 않는 결과)가 몇 개 구현에서 나옵니다.
- 실험해 보기 전에는 거의 브루트포스로 구현한 f, f2 가 덜 정확할거라고 생각했는데, 약간 테크닉을 써서 로그, 지수 함수를 사용해서 구현한 것이 오히려 덜 정확하네요. 왜그럴까요?
- 그리고, 18, 19에서 절대 나와서는 안 되는 1보다 큰 결과가 나오네요. 이건.. 정말 예상 못한 결과네요. 버그가 뭘까요?
728x90
'프로그래밍 > Python' 카테고리의 다른 글
tksheet 으로 csv 파일 내용을 tkinter 창에서 보여주기 (0) | 2022.04.28 |
---|---|
python 3d plotting (0) | 2022.04.27 |
Q-Pochhammer (0) | 2022.04.08 |
0과 1 사이에서 랜덤하게 뽑은 숫자를 평균적으로 몇 번 더해야 1보다 커질까요? (0) | 2022.03.18 |
[파이썬초보] AttributeError: 'NoneType' object has no attribute (3) | 2022.01.27 |