![]() |
Hinweis zum euklidischen Algorithmus
Hi!
Ich hab mir heute den ![]() b=0 würde wegen Division durch 0 zu einem Fehler führen. Für b=1 würde die Funktion a als Ergebnis liefern (statt 1). ggT(0,b) ist als |b| definiert, gäbe aber 0 zurück. Folgende Implementierung berücksichtigt diese Fälle und ist außerdem schneller:
Delphi-Quellcode:
function ggT(A, B: Integer): Cardinal;
var Rest: Integer; begin while B <> 0 do begin Rest := A mod B; A := B; B := Rest; end; Result := Abs(A); end; |
Re: Hinweis zum euklidischen Algorithmus
Hallo Christian,
da hast du allerdings zwei dicke Klopse entdeckt - soviel zum Thema QM. Nur zwei Klopse deshalb, weil ggT(0, b) = |b| nicht ganz richtig ist - auch wenn du das eventuell bei Wikipedia so gelesen hast. Genauer gilt ggT(0, b) = b für jedes b ungleich 0. Es ist in der Mathematik allerdings üblich sich in diesem Zusammenhang auf positive Ergebnisse zu beschränken, da nach dem "Fundamentalsatz" der Zahlentheorie zur Teilbarkeit gilt: (1) Für alle n ungleich 0 gilt n teilt 0 und n teilt n (2) Ist m Teiler von n, so ist auch -m Teiler von n und m Teiler von -m Vergleiche: Bundschuh "Einführung in die Zahlentheorie" Springer: 2002; Kapitel 1.2 Für die Freunde der funktionalen Programmierung hier noch eine rekursive Lösung des Problems:
Delphi-Quellcode:
Die Beschränkung auf positive Ergebnisse mittels Abs() findet bei Bedarf außerhalb der Funktion statt.
function Gcd(n, m: Int64): Int64;
begin Result := Math.IfThen(m = 0, n, Gcd(m, n mod m)); end; // oder function Gcd(n, m: Int64): Int64; begin if m = 0 then Result := n else Result := Gcd(m, n mod m); end; Freundliche Grüße |
Re: Hinweis zum euklidischen Algorithmus
|
Re: Hinweis zum euklidischen Algorithmus
Guten Morgen Hawkeye,
functional programming ohne lazy evaluation - gefällt mir eigentlich auch nicht. Danke für dein aufmerksames Lesen. Freundliche Grüße |
Re: Hinweis zum euklidischen Algorithmus
Zitat:
Beispiel: ggt(-3,15) liefert je nach Rangecheck-Einstellung entweder 4294967293 oder Runtime error 201 bzw Exception. Ursache: Eingabe Integer, Ausgabe Cardinal. Wenn Integer verwendet werden, sollte auch abs benutzt werden, da mathematisch der ggt immer nicht negativ ist. Gruß Gammatester |
Re: Hinweis zum euklidischen Algorithmus
Zur Klarstellung:
nicht der Beitrag von Cöster ist fehlerhaft, sondern der Delphicode den Chakotay1308 in ![]()
Delphi-Quellcode:
Bei Cöster steht richtig Result := Abs(A). Allerdings sollte auch bei ihm Integer zurückgeliefert werden.
function ggT(A, B: Integer): Cardinal;
var Rest: Integer; begin while B <> 0 do begin Rest := A mod B; A := B; B := Rest; end; Result := A; end; Gammatester |
Re: Hinweis zum euklidischen Algorithmus
Das stimmt, wenn man Abs weglässt, muss man auch Integer statt Cardinal zurückgeben.
Zitat:
Zitat:
|
Re: Hinweis zum euklidischen Algorithmus
Zitat:
Zitat:
Genau, also warum sollte der Ergebnistyp ein anderer sein als der gemeinsame Ausgangstyp? Er ist ja auch nicht int64 oder uint64. Gammatester |
Re: Hinweis zum euklidischen Algorithmus
Zitat:
Zitat:
|
Re: Hinweis zum euklidischen Algorithmus
Dass -abs(d) < abs(d) gilt, ist auch nur eine Frage der Definition. Beachte: nicht immer arbeiten Mathematiker mit einem Zahlenstrahl, und selbst wenn, dann sieht der nicht immer so aus wie in der Grundschule ;)
Greetz alcaeus |
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:44 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz