Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Integerüberlauf bei Cardinalmultiplikation? (https://www.delphipraxis.net/53967-integerueberlauf-bei-cardinalmultiplikation.html)

Kedariodakon 26. Sep 2005 15:42


Integerüberlauf bei Cardinalmultiplikation?
 
Delphi-Quellcode:
Function   CmC:   Cardinal;
Var   c1:   Cardinal;
      c2:   Cardinal;
Begin
   c1         := 1000000000;
   c2         := 4;
   Result   := c1 * c2
End;
Weshalb gibt es bei der Funktion einen Integerüberlauf?
1.000.000.000 * 4 = 4.000.000.000
Wertebereich Cardinal: 0-4.294.967.295

Bye

Alex_ITA01 26. Sep 2005 15:45

Re: Integerüberlauf bei Cardinalmultiplikation?
 
Hallo erstmal,
bei mir geht folgender Source

Delphi-Quellcode:
Function  CmC:  Cardinal;
Var  c1:  Cardinal;
      c2:  Cardinal;
Begin
   c1         := 1000000000;
   c2         := 4;
   Result  := c1 * c2
End;

procedure TForm1.Button1Click(Sender: TObject);
begin
  ShowMessage('Ergebnis: ' + FloatToStrF(CmC,ffFixed,15,8));
end;
Liegt es an deinem System? Ich glaube Cardinal ist nicht immer gleich laut OnlineHilfe von Delphi?!

MFG Alex

edit: hab grad die OnlineHilfe gelesen und da steht: Diese Typen sollten immer verwendet werden... Sorry mein Fehler.Aber wie gesagt, bei mir gehts...

MFG Alex

Kedariodakon 26. Sep 2005 15:59

Re: Integerüberlauf bei Cardinalmultiplikation?
 
Delphi version?

Ich hab d7 + update
WinXP + SP2

Bye

Alex_ITA01 26. Sep 2005 16:01

Re: Integerüberlauf bei Cardinalmultiplikation?
 
diese Sachen habe ich auch alle beide (Delphi+XP).
Komisch...
Vielleicht weiß ja noch jemand, woran es liegen könnte.
Hast du das in einer komplexen Anwendung oder reicht es wie in meinem Beispiel mit einem Button und im OnClick passiert der Fehler?!

MFG Alex

sakura 26. Sep 2005 16:05

Re: Integerüberlauf bei Cardinalmultiplikation?
 
Zitat:

Zitat von Kedariodakon
Ich hab d7 + update
WinXP + SP2

Ich habe es jetzt mal ohne das Delphi Update in D7 getestet: no problems.

...:cat:...

Kedariodakon 26. Sep 2005 16:09

Re: Integerüberlauf bei Cardinalmultiplikation?
 
Zitat:

Zitat von Alex_ITA01
diese Sachen habe ich auch alle beide (Delphi+XP).
Komisch...
Vielleicht weiß ja noch jemand, woran es liegen könnte.
Hast du das in einer komplexen Anwendung oder reicht es wie in meinem Beispiel mit einem Button und im OnClick passiert der Fehler?!

MFG Alex

Mir ist es in einer komplexen Anwendung aufgefallen und habe es exportiert...

Und die oben gepostete Funktion knallt...
Ich kann es nicht nachvollziehen...


Bye

Sharky 26. Sep 2005 16:09

Re: Integerüberlauf bei Cardinalmultiplikation?
 
Unter D7 und D2k5 kein Problem. Unter D3 kommt es natürlich zu dem Überlauf.

Kedariodakon 26. Sep 2005 16:17

Re: Integerüberlauf bei Cardinalmultiplikation?
 
hat jemand eine idee warum ich das bekomm?
Kann mir das jemand kompilieren, dass ich mal eine von euch auf meinen Rechner testen kann?

Bye

Sharky 26. Sep 2005 16:22

Re: Integerüberlauf bei Cardinalmultiplikation?
 
Liste der Anhänge anzeigen (Anzahl: 1)
Der Code von Alex_ITA01 mit D7 prof compiliert:

Hador 26. Sep 2005 16:23

Re: Integerüberlauf bei Cardinalmultiplikation?
 
Liste der Anhänge anzeigen (Anzahl: 1)
bei mir funktioniert es auch. D7PE + WinXP


EDIT: Zu spät

Kedariodakon 26. Sep 2005 16:32

Re: Integerüberlauf bei Cardinalmultiplikation?
 
hmm es kommt nur wenn: Compielerschalter Project/Optionen/Compiler/Überlaufprüfung An ist, dies ist aber in allen meinen Projecten so...

Vielleicht könntet ihr ja mal schauen ob der bei euch gesetzt ist oder nicht.

Bye


Edit: BTW die demos gehen...

Hador 26. Sep 2005 16:36

Re: Integerüberlauf bei Cardinalmultiplikation?
 
Dann kommte bei mir auch 'n Integeroverflow Error

Sharky 26. Sep 2005 16:45

Re: Integerüberlauf bei Cardinalmultiplikation?
 
Zitat:

Zitat von Hador
Dann kommte bei mir auch 'n Integeroverflow Error

Bei D7 kommt tatsächlich der Fehler. Bei D2k5 nicht.

EDIT Ich habe eben mal das UpDate für Delphi 7 installiert. Jetzt kann ich den Fehler nicht mehr reproduzieren.

Flocke 26. Sep 2005 16:55

Re: Integerüberlauf bei Cardinalmultiplikation?
 
Bei mir klappts mit D2005, sowohl mit als auch ohne Überlaufprüfung.

Hab' gerade mal ein bisschen Disassembliert und dabei gesehen, dass Delphi je nach Einstellung eine der Instruktionen imul (ohne Überlaufprüfung) oder mul (mit Überlaufprüfung) erzeugt.

Code:
  ; Mit Prüfung            ; Ohne Prüfung
  mov ecx,$3b9aca00         mov eax,$3b9aca00       
  mov ebx,$00000004         mov edx,$00000004
  mov eax,ebx              imul edx
  mul ecx
  jnb @cont
  call @IntOver
@cont:
Vielleicht kann das einer mit 'ner anderen Delphi-Version mal nachvollziehen?

Also: Breakpoint auf die Multiplikation und wenn Delphi hält dann Ansicht -> Debug Fenster -> CPU.

Vielleicht erzeugen andere Delphi-Versionen bei Optimierung und Überlaufprüfung die falsche CPU-Instruktion - imul setzt nämlich das Carry-Flag, das bei "jnb @cont" überprüft wird, mul hingegen nicht.

Christian Seehase 26. Sep 2005 17:57

Re: Integerüberlauf bei Cardinalmultiplikation?
 
Moin Volker,

unter D7Pro SP1 => exakt die gleichen Routinen wie bei Dir.

himitsu 26. Sep 2005 18:10

Re: Integerüberlauf bei Cardinalmultiplikation?
 
Dat is'n Problem des DelphiCompilers ... es wird oftmals nicht wirklich darauf geachtet, ob signed, oder unsigned Integerroutinen verwendet werden.

die Überlaufkontrollen sind fast überall nur als signed Integer-Routinen engebunden, wodurch dann natürlch auf die Charakeristik des Integers geprüft wird.

Am Meißten gibt's da ja bei den 64-Bit-Struckturen massive Probleme.


Und in diesem Fall würde es nichtmal was bringen, wenn du direkt einen bestimmten Typ angibst:
Delphi-Quellcode:
Function  CmC:  LongWord;
Var  c1:  LongWord;
      c2:  LongWord;
Begin
   c1         := 1000000000;
   c2         := 4;
   Result  := c1 * c2 
End;



Also entweder läßt du dir Überlaufprüfung komplett weg, oder du schaltest sie halt in diesem speziellen Fall ab - ich glaub mit {$O-} und dnach dann natürlich wieder an.
Notfalls und wenn erwünscht mußt di dann halt selber die Überlaufprüfung Programmieren.

Einen anderen Weg gibt's wohl nicht ... du kannst dir natürlich auch 'ne Delphi-Version suchen, wo es richtig implementiert ist.

Christian Seehase 26. Sep 2005 18:30

Re: Integerüberlauf bei Cardinalmultiplikation?
 
Moin Zusammen,

so, ich hab' das jetzt noch einmal probiert mit D7Pro ohne SP1:

Delphi-Quellcode:
;Mit Prüfung
mov eax,$3b9aca00
mov edx,$00000004
imul edx
jnb +$05
call @IntOver
ret
Der Fehler eine vorzeichenbehaftete Multiplikation bei vorzeichenlosen Operanden durchzuführen, wurde bei SP1 also behoben.

NicoDE 26. Sep 2005 19:03

Re: Integerüberlauf bei Cardinalmultiplikation?
 
Workaround (der allerdings etwas Performance kostet)
Delphi-Quellcode:
function CmC: Cardinal;
var
  c1: Cardinal;
  c2: Cardinal;
begin
  c1 := 1000000000;
  c2 := 4;
  Result := Int64(c1) * Int64(c2);
end;

alzaimar 26. Sep 2005 19:37

Re: Integerüberlauf bei Cardinalmultiplikation?
 
D6SP2 => imul

Kedariodakon 26. Sep 2005 20:39

Re: Integerüberlauf bei Cardinalmultiplikation?
 
Ich habe das ATM auch mit int64 gelöst @Nico, wollte aber nun mal wissen an was das so liegt...

Bye

Flocke 26. Sep 2005 20:54

Re: Integerüberlauf bei Cardinalmultiplikation?
 
Zitat:

Zitat von Himitsu
Dat is'n Problem des DelphiCompilers ... es wird oftmals nicht wirklich darauf geachtet, ob signed, oder unsigned Integerroutinen verwendet werden.

Der einzige Grund könnte sein, dass vielleicht imul ein wenig schneller ist als mul. Wenn nur 32-Bits benötigt werden ist die Instruktion egal (s.u.). Allerdings brauchen laut Intel Spec. beide Instruktionen 3 µ-Ops, sollten also gleiche Laufzeit haben; auch werden beide in der U-Pipe ausgeführt. Vielleicht eine Optimierung für Prä-P4 CPUs (die Specs hab' ich nicht).

Zitat:

Zitat von Christian Seehase
Der Fehler eine vorzeichenbehaftete Multiplikation bei vorzeichenlosen Operanden durchzuführen, wurde bei SP1 also behoben.

Die vorzeichenbehaftete Multiplikation ist ja nicht der Fehler - da eh nur die unteren 32 Bits interessieren ist das Ergebnis gleich.

Beispiel (für 4-Bit x 4-Bit => 8-Bit):
Code:
1010 x 0101 = (10 x 5) = 50 = 0011[b]0010[/b]
1010 x 0101 = (-6 x 5) = -30 = 1110[b]0010[/b]
(die unteren 4 Bits sind gleich)

Das Problem ist, dass er danach über das Carry-Flag prüft ob ein Überlauf eingetreten ist (was bei imul der Fall ist, bei mul aber nicht) - und das ist falsch.

Aber wenn's mit Service Packs behoben wird, dann ist's ja in Ordnung.
IMHO ist aber durchaus sinnvoll, für ein Release die Überlaufprüfung auszuschalten.

(Edit: Tippfehler korrigiert)

himitsu 26. Sep 2005 22:43

Re: Integerüberlauf bei Cardinalmultiplikation?
 
net wirklich ... in der System-Unit gibt ja z.B. einige Routinen für die 64-Bit-Berechnung (je eine Variante mit und eine ohne Vorzeichen) und der Compiler nimmt halt mit Vorliebe die nur die signed-Versionen auch wenn es sich um LargeWord (unsigned) handelt ... vom aufbau her sind allerdings beide Prozeduren her fast gleich lang.

(ohne Überlaufprüfung) gibt es bei der Addition/Substraction kein Probleme und bei der multiplication fällt es auch kaum auf ... aber wenn man mal die divisionen(mul/div) betrachte . dann sieht das net mehr so net aus -.-''

aus diesem Grud hab i mir z.B. diese Funktionen mal extrahiert und rufe sie jetzt direkt auf (i nehme halt die Verantwortung dem Delphi ab)

Flocke 27. Sep 2005 09:12

Re: Integerüberlauf bei Cardinalmultiplikation?
 
Hab' auch gerade mal in die System-Unit geschaut. Bei den vorzeichenbehafteten 64-Bit-Operationen gibt's jeweils Versionen mit und ohne Überlaufprüfung und bei denen mit steht der folgende Kommentar:
Zitat:

Zitat von System.pas
64-bit signed multiply, with overflow check (98.05.15: overflow not supported yet)
64-bit signed division with overflow check (98.05.15: not implementated yet)
64-bit signed modulo with overflow (98.05.15: overflow not yet supported)

Offensichtlich hat seit Mai '98 Niemand daran gedacht, die Überlaufprüfungen zu implementieren ... :?

himitsu 27. Sep 2005 09:34

Re: Integerüberlauf bei Cardinalmultiplikation?
 
Hab ja gestagt, dat da einiges fehlt.

Und im Grunde genommen bleiben da nur noch drei Möglichkeiten, wenn man 100%ig sicher gehen will.
  • nur noch signet Integer (ShortInt, SmallInt, LongInt und LargeInt/Int64) verwenden
  • selber die nötigen Routionen bereit stellen
  • oder die krasse Variante:
    bei Programmstart den Status prüfen und wenn Fehler dat Programm wieder beenden ._.

Marcel Gascoyne 27. Sep 2005 10:08

Re: Integerüberlauf bei Cardinalmultiplikation?
 
Der Fehler ist bereits bekannt (siehe QC#2571), wurde in Delphi 7.1 (Build 7.0.8.1) behoben.

Gruß,
Marcel


Alle Zeitangaben in WEZ +1. Es ist jetzt 03:25 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