julia> 0.5 + 0.25 == 0.75
true
julia> 0.1 + 0.2 == 0.3
false
using Polynomials: Polynomial, fromroots
import PolynomialRoots: roots
wilkinson(n) = fromroots(1.0:n)
roots(poly::Polynomial) = roots(poly.coeffs)
julia> round.(roots(wilkinson(3)),
digits = 4)
3-element Vector{ComplexF64}:
3.0 - 0.0im
2.0 + 0.0im
1.0 + 0.0im
julia> w20 = wilkinson(20);
julia> round.(roots(w20), digits = 4)
20-element Vector{ComplexF64}:
19.9999 - 0.0im
19.0006 + 0.0im
17.9973 + 0.0im
17.0074 + 0.0im
15.9855 + 0.0im
15.0204 + 0.0im
13.9779 + 0.0im
13.0184 + 0.0im
⋮
julia> w20[19] -= 2^-23
julia> round.(roots(w20), digits = 4)
20-element Vector{ComplexF64}:
20.8469 - 0.0im
19.5024 + 1.9403im
19.5024 - 1.9403im
13.9923 - 2.5188im
13.9923 + 2.5188im
16.7307 + 2.8126im
16.7307 - 2.8126im
11.7935 + 1.6521im
⋮
julia> round.(abs.(roots(w20)), digits = 4)
20-element Vector{Float64}:
20.8469
19.5987
19.5987
14.2172
14.2172
16.9655
16.9655
11.9086
11.9086
10.1158
⋮
f(x) = 4.0 * x * (1.0 - x)
function suite_log(n, x0)
for _ ∈ 1:n
x0 = f(x0)
end
x0
end
julia> using Random: Xoshiro
julia> x0 = rand(Xoshiro(45))
julia> suite_log(10000000, x0)
0.0
julia> 1e308
1.0e308
julia> 1e308 * 2.0
Inf
julia> 5e-324 - 2e-324
5.0e-324
julia> 5e-324 - 3e-324
0.0
Si le résultat d'un calcul est "correct", l'erreur absolue avec la véritable réponse peut aller jusqu'à \( \frac 1 2 \) ulp!
setprecision(500) do
w20_big = wilkinson(BigFloat(20))
global roots_w20_big = roots(w20_big)
w20_big[19] -= 2.0^-23.0
global roots_w20_big_pert = roots(w20_big)
end
julia> round.(roots_w20_big, digits = 4)
20-element Vector{Complex{BigFloat}}:
20.0 - 0.0im
19.0 + 0.0im
18.0 + 0.0im
17.0 + 0.0im
16.0 + 0.0im
15.0 + 0.0im
14.0 + 0.0im
13.0 + 0.0im
12.0 + 0.0im
11.0 + 0.0im
⋮
julia> mags = Float64.(abs.(roots_w20_big_pert))
julia> round.(mags, digits = 4)
20-element Vector{Float64}:
20.8469
19.5987
19.5987
14.2173
14.2173
16.9655
16.9655
11.9088
11.9088
⋮
P. Fournier (STATQAM — UQAM) Séminaire AECSM 9 novembre 2022