![]() |
Integerüberlauf bei Cardinalmultiplikation?
Delphi-Quellcode:
Weshalb gibt es bei der Funktion einen Integerüberlauf?
Function CmC: Cardinal;
Var c1: Cardinal; c2: Cardinal; Begin c1 := 1000000000; c2 := 4; Result := c1 * c2 End; 1.000.000.000 * 4 = 4.000.000.000 Wertebereich Cardinal: 0-4.294.967.295 Bye |
Re: Integerüberlauf bei Cardinalmultiplikation?
Hallo erstmal,
bei mir geht folgender Source
Delphi-Quellcode:
Liegt es an deinem System? Ich glaube Cardinal ist nicht immer gleich laut OnlineHilfe von Delphi?!
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; 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 |
Re: Integerüberlauf bei Cardinalmultiplikation?
Delphi version?
Ich hab d7 + update WinXP + SP2 Bye |
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 |
Re: Integerüberlauf bei Cardinalmultiplikation?
Zitat:
...:cat:... |
Re: Integerüberlauf bei Cardinalmultiplikation?
Zitat:
Und die oben gepostete Funktion knallt... Ich kann es nicht nachvollziehen... Bye |
Re: Integerüberlauf bei Cardinalmultiplikation?
Unter D7 und D2k5 kein Problem. Unter D3 kommt es natürlich zu dem Überlauf.
|
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 |
Re: Integerüberlauf bei Cardinalmultiplikation?
Liste der Anhänge anzeigen (Anzahl: 1)
Der Code von Alex_ITA01 mit D7 prof compiliert:
|
Re: Integerüberlauf bei Cardinalmultiplikation?
Liste der Anhänge anzeigen (Anzahl: 1)
bei mir funktioniert es auch. D7PE + WinXP
EDIT: Zu spät |
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... |
Re: Integerüberlauf bei Cardinalmultiplikation?
Dann kommte bei mir auch 'n Integeroverflow Error
|
Re: Integerüberlauf bei Cardinalmultiplikation?
Zitat:
EDIT Ich habe eben mal das UpDate für Delphi 7 installiert. Jetzt kann ich den Fehler nicht mehr reproduzieren. |
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:
Vielleicht kann das einer mit 'ner anderen Delphi-Version mal nachvollziehen?
; 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: 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. |
Re: Integerüberlauf bei Cardinalmultiplikation?
Moin Volker,
unter D7Pro SP1 => exakt die gleichen Routinen wie bei Dir. |
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. |
Re: Integerüberlauf bei Cardinalmultiplikation?
Moin Zusammen,
so, ich hab' das jetzt noch einmal probiert mit D7Pro ohne SP1:
Delphi-Quellcode:
Der Fehler eine vorzeichenbehaftete Multiplikation bei vorzeichenlosen Operanden durchzuführen, wurde bei SP1 also behoben.
;Mit Prüfung
mov eax,$3b9aca00 mov edx,$00000004 imul edx jnb +$05 call @IntOver ret |
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; |
Re: Integerüberlauf bei Cardinalmultiplikation?
D6SP2 => imul
|
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 |
Re: Integerüberlauf bei Cardinalmultiplikation?
Zitat:
Zitat:
Beispiel (für 4-Bit x 4-Bit => 8-Bit):
Code:
(die unteren 4 Bits sind gleich)
1010 x 0101 = (10 x 5) = 50 = 0011[b]0010[/b]
1010 x 0101 = (-6 x 5) = -30 = 1110[b]0010[/b] 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) |
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) |
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:
|
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.
|
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 21:56 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 by Thomas Breitkreuz