Autor Beitrag
Hidden
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 2242
Erhaltene Danke: 55

Win10
VS Code, Delphi 2010 Prof.
BeitragVerfasst: 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:
ausblenden Delphi-Quelltext
1:
2:
0111111111  //Das markierte Bit Enthält das Vorzeichen.
1000000000  //Beim überlauf gibt es einen Vorzeichenwechsel.


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:
ausblenden 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{Strg+a} then
        SelectAll
      else if Key = char(vk_Return) then begin
        Text := Copy(Text, 1, SelStart);  {Reihe bei Cursorposition beginnen,
                                           Rest wegschneiden}

        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;
          //bei Überlauf gibt es einen Vorzeichenwechsel
          while (Sign(Zahl1) = Sign(Zahl2)) or  //ups hier muss ein "or" hin, war vorher "and"
                (Abs(Zahl2) < High(Int64) div 2do 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 user profile iconNarses: 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
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 478

Windows XP Home
Delphi 2005, RAD Studio 2007, MASM32, FASM, SharpDevelop 3.0
BeitragVerfasst: 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 :wink: ):
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:
user profile iconHidden 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 :wink: )

_________________
Religionskriege sind nur Streitigkeiten darüber, wer den cooleren imaginären Freund hat ;-)
Timosch
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 1314

Debian Squeeze, Win 7 Prof.
D7 Pers
BeitragVerfasst: Di 25.03.08 17:35 
user profile iconSilas 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...


user profile iconSilas hat folgendes geschrieben:

user profile iconHidden 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 :wink: )

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



BeitragVerfasst: Di 25.03.08 17:44 
OVERFLOW Checking
Einloggen, um Attachments anzusehen!
Silas
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 478

Windows XP Home
Delphi 2005, RAD Studio 2007, MASM32, FASM, SharpDevelop 3.0
BeitragVerfasst: Di 25.03.08 17:54 
user profile iconTimosch 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.

user profile iconTimosch 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)

user profile iconTimosch 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1654
Erhaltene Danke: 244

WIN10,PuppyLinux
FreePascal,Lazarus
BeitragVerfasst: 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
ausblenden 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 ;{power}

function fibo(int n):Int64;// in TurboPascal comp 
consturbo
  Wur5 : extended = sqrt(5);
  {phi = (1+sqrt(5)/2} // = fib(n+1)/fib(n) fuer n -> unendlich
  phi : extended = 1.618033989...;
  {Rho = (1-sqrt(5)/2 = -phi +1}
  rho : extended = -0.618033989;
{vielleicht ausrechnen und hinschreiben)
var
begin
  fibo := round((power(phi,n)+power(rho,n))/Wur5);
end;


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
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 478

Windows XP Home
Delphi 2005, RAD Studio 2007, MASM32, FASM, SharpDevelop 3.0
BeitragVerfasst: Di 25.03.08 18:16 
user profile iconHorst_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. :wink: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 2242
Erhaltene Danke: 55

Win10
VS Code, Delphi 2010 Prof.
BeitragVerfasst: Di 25.03.08 18:25 
@user profile iconHorst_H: Klar :D 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1654
Erhaltene Danke: 244

WIN10,PuppyLinux
FreePascal,Lazarus
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 510

Win XP Prof
Delphi 7 E
BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 2242
Erhaltene Danke: 55

Win10
VS Code, Delphi 2010 Prof.
BeitragVerfasst: Di 25.03.08 18:35 
Naja im Prinzip will ich die Reihe :D

@user profile iconAllesquarks: 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
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 478

Windows XP Home
Delphi 2005, RAD Studio 2007, MASM32, FASM, SharpDevelop 3.0
BeitragVerfasst: Di 25.03.08 18:36 
user profile iconAllesquarks 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 :wink: .

_________________
Religionskriege sind nur Streitigkeiten darüber, wer den cooleren imaginären Freund hat ;-)
Hidden Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 2242
Erhaltene Danke: 55

Win10
VS Code, Delphi 2010 Prof.
BeitragVerfasst: 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) :gruebel:
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. :dunce:

_________________
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



BeitragVerfasst: Sa 26.04.08 19:56 
user profile iconSilas hat folgendes geschrieben:
user profile iconAllesquarks 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?