Praktische Mathematik: Symbolisches Rechnen — Praktikumsblatt 1

Werbung
Praktische Mathematik: Symbolisches Rechnen — Praktikumsblatt 1
Prof. Dr. Claus Fieker
Abgabe bis Freitag, 12.5.2017, 12:00 Uhr
Sommersemester 2017
Dr. Tommy Hofmann
Aufgabe 1.
(i) Implementiere eine Funktion my_gcd(f, g), die für gegebene univariate Polynome f, g über einem Körper
den größten gemeinsamen Teiler zurückgibt (normiert mit Leitkoeffizient 1).
(ii) Implementiere eine Funktion my_xgcd(f, g), die für gegebene univariate Polynome f, g über einem Körper
ein Tripel (g, u, v) von Polynomen zurück gibt, so dass g = ggT(f, g) und g = uf + vg.
(iii) Implementiere eine Funktion my_pseudo_div(f, g), die für zwei gegebene Polynome f, g über einem Ring
eine Pseudo-Division wie in Aufgabe 1, Blatt 1 liefert. Rückgabe ist ein Tupel (q, r) von Polynomen.
(iv) Modifiziert die Funktionen derart, dass sie ein drittes optionales Argument verbose = false haben.
Falls verbose == true, soll in jedem Schritt die Größe der Zwischenergebnisse ausgegeben werden. Nutze
hierfür die Funktion height(f), die für ein Polynom f über Q den Koeffizienten mit der größten Höhe
zurück gibt, wobei die Höhe von ab gleich max(|a|, |b|) ist.
Aufgabe 2. Wir wollen Ganzzahlarithmetik mit beliebig großen Zahlen implementieren. Unsere kleinsten
Blöcke sind hierfür Zahlen a im Bereich 0 ≤ a ≤ 264−1 , die in julia vom Typ UInt sind. Eine beliebig große Zahl
ist also eine Liste von Elementen vom Type UInt, hat also selbst den Typ Array{UInt, 1}. Beispielsweise soll
[UInt(1), UInt(0), UInt(3)] der Zahl 1 · (264 )0 + 0 · (264 )1 + 3 · (264 )2 entsprechen.
(i) Schreibe eine Funktion my_add(A::Array{UInt, 1}, B::Array{UInt, 1}) die zwei Zahlen addiert. Nutze
hierfür die Funktion add_with_carry(a::UInt, b::UInt) -> UInt, Bool, welche zwei Zahlen im Bereich [0, 264 − 1] modulo 264 addiert. Der zweite Rückgabewert gibt an, ob ein Übertrag (carry) vorhanden
ist.
Alternativ könnt ihr die Funktion add_with_carry(a::UInt, b::UInt, c::Bool) -> UInt, Bool nutzen,
die für c = false das gleiche macht wie add_with_carry(a, b) und für c = true die Addition von
a + b + 1 modulo 264 durchführt.
(ii) Schreibe eine Funktion my_mul(A::Array{UInt, 1}, B::Array{UInt, 1}) die zwei Zahlen multipliziert.
Nutze hierfür die Funktion mult_long(a::UInt, b::UInt) -> UInt, UInt, welche zwei Zahlen im Bereich [0, 264 − 1] multipliziert. Ist mult_long(a, b) = c, d, so gilt a · b = c + d · 264 .
Hinweis zu Aufgabe 2: Man kann zwischen den in julia eingebauten Zahlen und unseren Zahlen hin und her
wechseln:
julia> long_int(BigInt(2)^128)
3-element Array{UInt64,1}:
0x0000000000000000
0x0000000000000000
0x0000000000000001
julia> long_int(BigInt(2)^128 + BigInt(2)^64)
3-element Array{UInt64,1}:
0x0000000000000000
0x0000000000000001
0x0000000000000001
julia> BigInt([UInt(1)])
1
julia> BigInt([UInt(1), UInt(1)])
18446744073709551617
Ihr dürft die Funktionen aber nicht zur Lösung der Aufgabe benutzen.
1
Herunterladen