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