AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Hinweis zum euklidischen Algorithmus

Ein Thema von Cöster · begonnen am 8. Feb 2007 · letzter Beitrag vom 16. Mär 2007
Antwort Antwort
Seite 1 von 2  1 2      
Cöster

Registriert seit: 6. Jun 2006
589 Beiträge
 
Turbo Delphi für Win32
 
#1

Hinweis zum euklidischen Algorithmus

  Alt 8. Feb 2007, 16:17
Hi!

Ich hab mir heute den Code-Library-Eintrag zum Euklidschen Algorithmus angesehen. Die dort gepostete Implementierung berücksichtigt einige Sonderfälle nicht:

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;
  Mit Zitat antworten Zitat
marabu

Registriert seit: 6. Apr 2005
10.109 Beiträge
 
#2

Re: Hinweis zum euklidischen Algorithmus

  Alt 8. Feb 2007, 18:03
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:
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;
Die Beschränkung auf positive Ergebnisse mittels Abs() findet bei Bedarf außerhalb der Funktion statt.

Freundliche Grüße
  Mit Zitat antworten Zitat
Hawkeye219

Registriert seit: 18. Feb 2006
Ort: Stolberg
2.227 Beiträge
 
Delphi 2010 Professional
 
#3

Re: Hinweis zum euklidischen Algorithmus

  Alt 8. Feb 2007, 23:21
Hallo marabu,

die Lösung mit "IfThen" gefällt mir nicht. Da war doch mal was...

Gruß Hawkeye
  Mit Zitat antworten Zitat
marabu

Registriert seit: 6. Apr 2005
10.109 Beiträge
 
#4

Re: Hinweis zum euklidischen Algorithmus

  Alt 9. Feb 2007, 06:02
Guten Morgen Hawkeye,

functional programming ohne lazy evaluation - gefällt mir eigentlich auch nicht. Danke für dein aufmerksames Lesen.

Freundliche Grüße
  Mit Zitat antworten Zitat
gammatester

Registriert seit: 6. Dez 2005
999 Beiträge
 
#5

Re: Hinweis zum euklidischen Algorithmus

  Alt 14. Mär 2007, 08:30
Zitat von Cöster:
Hi!

Ich hab mir heute den Code-Library-Eintrag zum Euklidschen Algorithmus angesehen. Die dort gepostete Implementierung berücksichtigt einige Sonderfälle nicht:

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;
Da ich nicht weiß, wie man einen Code-Library-Beitrag kommentiert, also hier der Hinweis, daß dieser Code eine "Verschlimmbesserung" ist: Ein Speziallfall wird repariert, aber in ca der Hälfte aller Fehler werden neue Fehler/Bugs eingebaut:

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
  Mit Zitat antworten Zitat
gammatester

Registriert seit: 6. Dez 2005
999 Beiträge
 
#6

Re: Hinweis zum euklidischen Algorithmus

  Alt 14. Mär 2007, 12:32
Zur Klarstellung:

nicht der Beitrag von Cöster ist fehlerhaft, sondern der Delphicode den Chakotay1308 in Code-Library-Eintrag zum Euklidschen Algorithmus daraus ableitet.

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 := A;
end;
Bei Cöster steht richtig Result := Abs(A). Allerdings sollte auch bei ihm Integer zurückgeliefert werden.

Gammatester
  Mit Zitat antworten Zitat
Cöster

Registriert seit: 6. Jun 2006
589 Beiträge
 
Turbo Delphi für Win32
 
#7

Re: Hinweis zum euklidischen Algorithmus

  Alt 14. Mär 2007, 18:35
Das stimmt, wenn man Abs weglässt, muss man auch Integer statt Cardinal zurückgeben.

Zitat von gammatester:
da mathematisch der ggt immer nicht negativ ist.
jetzt doch? Ich blick gerade nicht mehr durch: Wikipedia sagt nicht negativ, weswegen ich auch Abs benutzt hatte. Marabu widerspricht und du stimmst mir wieder zu. Was ist denn jetzt richtig?

Zitat von gammatester:
Allerdings sollte auch bei ihm Integer zurückgeliefert werden.
Wieso? Wenn sich das Ergebnis sowieso im Bereich zwischen 0 und 2147483647 müsste es doch eig. egal sein.
  Mit Zitat antworten Zitat
gammatester

Registriert seit: 6. Dez 2005
999 Beiträge
 
#8

Re: Hinweis zum euklidischen Algorithmus

  Alt 15. Mär 2007, 08:11
Zitat von Cöster:
:wiejetzt: jetzt doch? Ich blick gerade nicht mehr durch: Wikipedia sagt nicht negativ, weswegen ich auch Abs benutzt hatte. Marabu widerspricht und du stimmst mir wieder zu. Was ist denn jetzt richtig?
Richtig ist abs, das kann man leicht einsehen: ggt ist der größte gemeinsame Teiler. Wenn also -abs(d) und abs(d) gemeinsame Teiler sind, ist doch wohl abs(d) der größere.

Zitat von Cöster:
Zitat von gammatester:
Allerdings sollte auch bei ihm Integer zurückgeliefert werden.
Wieso? Wenn sich das Ergebnis sowieso im Bereich zwischen 0 und 2147483647 müsste es doch eig. egal sein.

Genau, also warum sollte der Ergebnistyp ein anderer sein als der gemeinsame Ausgangstyp? Er ist ja auch nicht int64 oder uint64.

Gammatester
  Mit Zitat antworten Zitat
Cöster

Registriert seit: 6. Jun 2006
589 Beiträge
 
Turbo Delphi für Win32
 
#9

Re: Hinweis zum euklidischen Algorithmus

  Alt 15. Mär 2007, 12:14
Zitat von gammatester:
warum sollte der Ergebnistyp ein anderer sein als der gemeinsame Ausgangstyp?
Warum sollte der Ergebnistyp kein anderer sein als der gemeinsame Ausgangstyp? Wenn's Cardinal ist, sieht jeder sofort, dass der Rückgabewert positiv ist, auch ohne in den Code zu gucken.

Zitat von gammatester:
Er ist ja auch nicht int64 oder uint64.
Weil das (im Gegensatz zu Integer/Cardinal) den Nachteil hätte, dass der Rückgabewert doppelt so viel Speicher einnimmt.
  Mit Zitat antworten Zitat
Benutzerbild von alcaeus
alcaeus

Registriert seit: 11. Aug 2003
Ort: München
6.537 Beiträge
 
#10

Re: Hinweis zum euklidischen Algorithmus

  Alt 15. Mär 2007, 12:18
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
Andreas B.
Die Mutter der Dummen ist immer schwanger.
Ein Portal für Informatik-Studenten: www.infler.de
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:36 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz