連分数展開
continued fraction
$ \pi = 3 + \cfrac{1}{7 + \cfrac{1}{15 + \cfrac{1}{1 + \cfrac{1}{\ddots}}}}
$ \pi= [3; 7, 15, 1,\cdots]
小数を連分数展開する
計算誤差をいい感じに吸収しないといけないあんも.icon
元の有効数字と処理回数からいい感じに指定できる?
任意精度にできる?あんも.icon
実際は30項目くらいで破綻する
中身をいい感じにすればできそう?
code:jl
function continued_frac(number::Real, max_terms::Int; tolerance = 1e-3)
frac_terms = Int[]
for _ in 1:max_terms
int_part = floor(Int, number)
push!(frac_terms, int_part)
frac_part = number - int_part
if abs(frac_part) < tolerance # frac_part ≈ 0 ではうまく止まらない
break
end
number = 1 / frac_part
end
return frac_terms
end
continued_frac(π,4)
continued_frac(0.259259, 5)
有理数の場合はユークリッドの互除法と対応する
中学受験の問題に出るらしい?あんも.icon
code:jl
function continued_frac(rational::Tuple{Int, Int}, max_terms::Int)
frac_terms = Int[]
nume = rational1
deno = rational2
for _ in 1:max_terms
quotient = nume ÷ deno
push!(frac_terms, quotient)
remainder = nume % deno
if remainder == 0
break
end
nume, deno = deno, remainder
end
return frac_terms
end
continued_frac((355, 113), 4)
continued_frac((259, 999), 5)
逆の操作で近似が得られる
円周率の近似値を得られる
355÷113
有理数であれば既約分数にできる
code:jl
function rev_continued_frac(frac_terms::Vector{Int})
nume = frac_termsend
deno = 1
for a in reverse(frac_terms1:end-1)
nume, deno = a * nume + deno, nume
end
return (nume, deno)
end
rev_continued_frac(continued_frac(π, 4))
rev_continued_frac(continued_frac(0.259259, 5))
rev_continued_frac(continued_frac((259, 999), 5))
漸化式を利用する?