Autor |
Beitrag |
Hidden
      
Beiträge: 2242
Erhaltene Danke: 55
Win10
VS Code, Delphi 2010 Prof.
|
Verfasst: Di 25.03.08 15:08
Hi,
Ich lasse bei einem Algorithmus zur Fibanacci-Reihe eineInt64-Variable absichtlich überlaufen und wollte fragen, ob es da zu Komplikationen kommen kann: Das ganze sieht so aus:
Delphi-Quelltext 1: 2:
| 0111111111 1000000000 |
Ich frage mich aber, ob das Bit vor dem Vorzeichen beim Überlauf verändert wird. Das wäre fatal, da es ja ncihtmehr zur Variable gehört. Meine Frage wäre jetzt, ob ich damit Probleme verursache und, ob es sinnvoll und möglich ist, auf den Speicherplatz davor ein Byte zu legen und es auf 0 zu setzen. Damit wäre gewährleistet, dass das beim Überlauf beeinflusste Bit innerhalb der Anwendung liegt.
Erkennt Delphi eventuell, dass dieses Problem besteht und reserviert diesen Speicherplatz zusätzlich?
Hier der Source:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28:
| procedure TFibonacci_Form.Fibonacci_Reihe_MemoKeyPress(Sender: TObject; var Key: Char); var Zahl1, Zahl2, Speicher: Int64; begin with Fibonacci_Reihe_Memo do if Key = #1 then SelectAll else if Key = char(vk_Return) then begin Text := Copy(Text, 1, SelStart); if TryStrToInt64(Lines.Strings[Lines.Count - 2], Zahl1) and TryStrToInt64(Lines.Strings[Lines.Count - 1], Zahl2) then begin Speicher := Zahl1 + Zahl2; if Speicher = 0 then Exit; Zahl1 := Zahl2; Zahl2 := Speicher; while (Sign(Zahl1) = Sign(Zahl2)) or (Abs(Zahl2) < High(Int64) div 2) do begin Lines.Append(IntToStr(Speicher)); Speicher := Zahl1 + Zahl2; Zahl1 := Zahl2; Zahl2 := Speicher; end; end; end; end; |
mfG,
Edit: Algo markiert.
Edit2: Was ist das denn? die Zeile zwischendrin ist nicht markiert und die normale Klammer in der Zeile wird als Kommentarklammer angesehen...
Edit3: Programm angehängt.
Edit4: Programm erneuert.
Edit5: and -> or; Dateianhang entsprechend erneuert
Moderiert von Narses: Topic aus Delphi Language (Object-Pascal) / CLX verschoben am Di 25.03.2008 um 14:12
Einloggen, um Attachments anzusehen!
_________________ Centaur spears can block many spells, but no one tries to block if they see that the spell is a certain shade of green. For this purpose it is useful to know some green stunning hexes. (HPMoR)
Zuletzt bearbeitet von Hidden am Di 25.03.08 21:55, insgesamt 5-mal bearbeitet
|
|
Silas
      
Beiträge: 478
Windows XP Home
Delphi 2005, RAD Studio 2007, MASM32, FASM, SharpDevelop 3.0
|
Verfasst: Di 25.03.08 17:06
Das Ganze sieht etwas anders aus.
Ich gehe jetzt mal davon aus, dass du noch nicht in Assembler programmiert hast, deswegen ein bisschen was zum Prozessor selbst (@ASM-Pros: Ich versuchs einfach zu erklärn, bitte nicht haun wenn net alles 100%ig stimmt  ):
Zum Rechnen wird intern als Daten(zwischen)speicher (so gut wie immer) mit sog. Registern gearbeitet. Sie befinden sich im Prozessor und sind immer so "breit" wie die Prozessorarchitektur, also meistens 32 oder 64 Bit (Auf 32-Bit-Systemen gibts für 64 Bit nen eigenen Befehlssatz, aber das ist hier nicht so wichtig).
Wenn ein solches Register voll ist, kann logischerweise nichts überlaufen, weil davor einfach nichts ist  . Aus 11111111 wird also 00000000, der Übertrag aus dem höchst Bit wird verworfen.
Damit sollte eigentlich klar sein, dass es keinen Überlauf geben kann. Alles, was den Wertebereich überschreitet, wird verworfen, und es geht eben bei Minus Zwei Milliarden und ein paar Zerquetschten wieder los.
BTW:
Hidden hat folgendes geschrieben: | Damit wäre gewährleistet, dass das beim Überlauf beeinflusste Bit innerhalb der Anwendung liegt. |
Andere Anwendungen "kaputtschreiben" ist bei Hardware-Multitasking sowieso so gut wie unmöglich. Mehr als eine AccessViolation wirst du so schnell nicht verursachen. (In diesem Fall (wenn er davor schreiben würde) sowieso nicht, aber das ist ein anderes Thema  )
_________________ Religionskriege sind nur Streitigkeiten darüber, wer den cooleren imaginären Freund hat
|
|
Timosch
      
Beiträge: 1314
Debian Squeeze, Win 7 Prof.
D7 Pers
|
Verfasst: Di 25.03.08 17:35
Silas hat folgendes geschrieben: |
Zum Rechnen wird intern als Daten(zwischen)speicher (so gut wie immer) mit sog. Registern gearbeitet. Sie befinden sich im Prozessor und sind immer so "breit" wie die Prozessorarchitektur, also meistens 32 oder 64 Bit (Auf 32-Bit-Systemen gibts für 64 Bit nen eigenen Befehlssatz, aber das ist hier nicht so wichtig). |
Haben denn 32-bit-Systeme 64-bit-Register? Wenn nicht, würde nämlich in der Tat der RAM verwendet werden...
Silas hat folgendes geschrieben: |
Hidden hat folgendes geschrieben: | Damit wäre gewährleistet, dass das beim Überlauf beeinflusste Bit innerhalb der Anwendung liegt. | Andere Anwendungen "kaputtschreiben" ist bei Hardware-Multitasking sowieso so gut wie unmöglich. Mehr als eine AccessViolation wirst du so schnell nicht verursachen. (In diesem Fall (wenn er davor schreiben würde) sowieso nicht, aber das ist ein anderes Thema ) |
Och, es geht schon. Diese Botschaft geht zumindest von den immer wieder kommenden Heap-/Stack-Overflow-Sicherheitslücken in vielen Programmen aus...
Aber gibt Delphi beim Überlauf nicht sowieso eine Fehlermeldung aus?
_________________ If liberty means anything at all, it means the right to tell people what they do not want to hear. - George Orwell
|
|
hathor
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Di 25.03.08 17:44
OVERFLOW Checking
Einloggen, um Attachments anzusehen!
|
|
Silas
      
Beiträge: 478
Windows XP Home
Delphi 2005, RAD Studio 2007, MASM32, FASM, SharpDevelop 3.0
|
Verfasst: Di 25.03.08 17:54
Timosch hat folgendes geschrieben: | Haben denn 32-bit-Systeme 64-bit-Register? |
Nein, aber die FPU (die für Fließkommaberechnungen zuständig ist) besitzt 80-Bit-Register. Diese werden bei MMX (so heißt der 64-Bit-Befehlssatz) als Register verwendet.
Timosch hat folgendes geschrieben: | Wenn nicht, würde nämlich in der Tat der RAM verwendet werden... |
Nein, würde er in den meisten Fällen nicht, da ein Prozessor keine zwei RAM-Variablen addieren kann. Es funktioniert nur Register-Register, Register-Konstante, Register-Variable und Variable-Konstante. Auch wenn nur im RAM addiert wird, ist die Zahlen-Breite auf diese 32 Bit beschränkt. (Außerdem wird ja mit Adressen gearbeitet, wodurch ein "Davor-Schreiben" gar nicht möglich wäre)
Timosch hat folgendes geschrieben: | Och, es geht schon. Diese Botschaft geht zumindest von den immer wieder kommenden Heap-/Stack-Overflow-Sicherheitslücken in vielen Programmen aus... |
Bei diesen Geschichten wird der Code des Programms selbst (!) mit Daten (z.B. aus einem vermeintlichen Bild) überschrieben. Das kann auftreten, wenn zu viele Daten auf den Stack gepusht (so nennt man das legen eines Wertes auf den Stack) werden, da der Stack rückwärts arbeitet, d.h. die Adresse des ersten Elements verkleinert sich beim pushen.
Absichtlich kann man einen anderen Prozess natürlich schon kaputt schreiben (siehe WriteProcessMemory), ich meinte hier eher aus Versehen.
_________________ Religionskriege sind nur Streitigkeiten darüber, wer den cooleren imaginären Freund hat
|
|
Horst_H
      
Beiträge: 1654
Erhaltene Danke: 244
WIN10,PuppyLinux
FreePascal,Lazarus
|
Verfasst: Di 25.03.08 18:09
Hallo,
@Silas:
einen Überlauf kannst Du wohl nicht verhindern.
Ein Byte( besser longint) davor zu setzen heisst auch anders rechnen zu müssen, da ein neuer Typ erzeugt wird, den Delphi so nicht unterstützt (zum Glück, was passierte , wenn man bei einem Überlauf einfach der Speicher davor oder dahinter ohne zu fragen mitbenutzte??? ) .
Man kann fibonacci auch ohne Summation berechnen, beispielsweise :
www.mathe.tu-freiber...afe/goldschnitt.html angewandt
www.webplain.de/fore...3208,3208#reply_3208
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26:
| function power(x,y : extended):extended; begin if y < 0 then power := 1/power(x,-y) else if y = 0 then if x = 0 then power := 0 else power := 1 else power := exp(x*ln(y)); end ;
function fibo(int n):Int64;consturbo Wur5 : extended = sqrt(5); phi : extended = 1.618033989...; rho : extended = -0.618033989; |
Du kannst aber auch units für Langzahlarithmetik benutzen BigInt von BenBe
oder
www.hsg-kl.de/faeche...pto/bignum/index.php
www.delphiforfun.org...ary/big_integers.htm
oder die sehr umfangreiche DEC_5_1c
oder www.michael-puff.de/...orte/Hagen_Reddmann/
Gruß Horst
|
|
Silas
      
Beiträge: 478
Windows XP Home
Delphi 2005, RAD Studio 2007, MASM32, FASM, SharpDevelop 3.0
|
Verfasst: Di 25.03.08 18:16
Horst_H hat folgendes geschrieben: | @Silas: einen Überlauf kannst Du wohl nicht verhindern. |
Nein, muss ich auch nicht, da es keinen geben kann. Glaubs mir einfach.  Zahlen haben immer eine konstante Größe (außer vielleicht BCD). Bei 32-Bit-Systemen ist ein Integer 4 Byte groß, auf 64-bittigen 8 Byte.
_________________ Religionskriege sind nur Streitigkeiten darüber, wer den cooleren imaginären Freund hat
|
|
Hidden 
      
Beiträge: 2242
Erhaltene Danke: 55
Win10
VS Code, Delphi 2010 Prof.
|
Verfasst: Di 25.03.08 18:25
@ Horst_H: Klar  aber wenn man sowieso alle Zahlen der Reihe(die im Int64-Definitionsbereich liegen) haben will, so ist dein Ansatz Zeitaufwendiger ;D.
Edit: Obwohl der Nutzer davon nichts merken sollte...
_________________ Centaur spears can block many spells, but no one tries to block if they see that the spell is a certain shade of green. For this purpose it is useful to know some green stunning hexes. (HPMoR)
Zuletzt bearbeitet von Hidden am Di 25.03.08 18:26, insgesamt 1-mal bearbeitet
|
|
Horst_H
      
Beiträge: 1654
Erhaltene Danke: 244
WIN10,PuppyLinux
FreePascal,Lazarus
|
Verfasst: Di 25.03.08 18:26
Hallo,
da habe ich Dich falsch verstanden.
Wie ich auch indirekt geschrieben habe, ein >Überlauf< (Carry bei positiven Ganzzahltypen(cardinal,word,byte), Overflow bei integer Typen (longint,shortint)) greift nicht im Speicher davor oder dahinter in irgendeiner Weise zu.
Gruß Horst
Edit @hidden: Ja ist das aufwendiger, wenn man alle haben will, aber wer will das schon.... 
|
|
Allesquarks
      
Beiträge: 510
Win XP Prof
Delphi 7 E
|
Verfasst: Di 25.03.08 18:30
Ja 32 Bit Architekturen haben nur 32 Bit register. Das sind die Allzweckregister. MMX ist mitnichten eine native 64 Bit Erweiterung, sondern vielmehr eine MultiMediaExtension, um gleichzeitig auf verschiedene Variablen die gleiche Operation anzuwenden.
Das Stichwort heißt hier Overflowchecking oder asm benutzen und zwar musst du das overflow Flag überprüfen. Int64 hat nämlich ein Vorzeichen Bit das heißt bei der Addition oder Subtraktion von int64 wird gewissermaßen nur das Vorzeichen überschrieben, was man aber über die Overflowchecks merkt und angemessen reagieren kann. Wenn du das ganze mit cardinalzahlen machst musst du das carry-Flag abfangen. Ich nehme an der Compiler wird in der Hochsprache eigenständig das richtige Flag überprüfen. Ist nicht wirklich schwer das Problem ist nur dass es in Delphi nativ keinen größeren Integertyp gibt da musst du dich dann mit Bigints befassen.
Ein bischen Eigenwerbung. In meinem Taschenrechner RAFX ist das drin kannst dir ja mal bei TInt64zahlimpl die Addition von zwei int64 ansehen. Das könntest du rüber copy und pasten.
|
|
Hidden 
      
Beiträge: 2242
Erhaltene Danke: 55
Win10
VS Code, Delphi 2010 Prof.
|
Verfasst: Di 25.03.08 18:35
Naja im Prinzip will ich die Reihe
@ Allesquarks: Naja, wie du dem o.ä. Algo entnehmen kannst mache ichs ja schon mit dem Vorzeichenwechsel.
[OT] Wens interessiert: hier ist das Progi, ist im Prinzip nichts anderes drin als der o.ä. Algo [/OT]
mfG,
Edit: Progi ist jetzt oben angehängt.
_________________ Centaur spears can block many spells, but no one tries to block if they see that the spell is a certain shade of green. For this purpose it is useful to know some green stunning hexes. (HPMoR)
Zuletzt bearbeitet von Hidden am Di 25.03.08 18:41, insgesamt 1-mal bearbeitet
|
|
Silas
      
Beiträge: 478
Windows XP Home
Delphi 2005, RAD Studio 2007, MASM32, FASM, SharpDevelop 3.0
|
Verfasst: Di 25.03.08 18:36
Allesquarks hat folgendes geschrieben: | MMX ist mitnichten eine native 64 Bit Erweiterung, sondern vielmehr eine MultiMediaExtension, um gleichzeitig auf verschiedene Variablen die gleiche Operation anzuwenden. |
Weiß ich, aber sie verwendet 64 Bit, die man eben trotz einer nativen 32-Bit Umgebung verwenden kann (ob Delphi nun MMX, SSE oder die FPU verwendet, weiß ich nicht).
Edit: @Hidden: Wäre schön, wenn man dein Programm ohne den Taskmanager beenden könnte  .
_________________ Religionskriege sind nur Streitigkeiten darüber, wer den cooleren imaginären Freund hat
|
|
Hidden 
      
Beiträge: 2242
Erhaltene Danke: 55
Win10
VS Code, Delphi 2010 Prof.
|
Verfasst: Di 25.03.08 18:47
äh... Komisch, jetzt steigt er bei mir auch nicht aus, bis gerade hat er das gemacht(schau dir mal die Abbruchbedingung an... eig. verursacht der overflow ein Vorzeichenwechsel)
Edit: Jetzt bricht er wieder ab, ich hab ncihts verändert. Kann es sein, dass das doch mit anderen Anwendungen wechselwirkt?
Edit2: äh, das Mysterium ist glaube ich gelöst, ich hatte Voher nciht recompiliert und die gepostete Programmversion ist nciht mit dem geposteten Code identisch, werde das korrigieren. 
_________________ Centaur spears can block many spells, but no one tries to block if they see that the spell is a certain shade of green. For this purpose it is useful to know some green stunning hexes. (HPMoR)
|
|
Grenzgaenger
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Sa 26.04.08 19:56
Silas hat folgendes geschrieben: | Allesquarks hat folgendes geschrieben: | MMX ist mitnichten eine native 64 Bit Erweiterung, sondern vielmehr eine MultiMediaExtension, um gleichzeitig auf verschiedene Variablen die gleiche Operation anzuwenden. | Weiß ich, aber sie verwendet 64 Bit, die man eben trotz einer nativen 32-Bit Umgebung verwenden kann (ob Delphi nun MMX, SSE oder die FPU verwendet, weiß ich nicht). |
oder 128Bit gross (XMM), je nach prozessor. aber mal was anderes, weshalb willste denn beim integer bleiben? wie wärs mit 'n real?
|
|
|