Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - 3000*1024*1024 = Overflow in conversion


maxk - Fr 16.07.04 13:01
Titel: 3000*1024*1024 = Overflow in conversion

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
const Max:Int64=3000*1024*1024// Overflow in conversion

var Max:Int64;
begin
 Max:=3000*1024*1024// Overflow in conversion
end;

var Max:Int64;
begin
 Max:=3000*1024;
 Max:=Max*1024// Fehlerfrei
end;
Okay, beiden beiden ersten Varianten meckert der Compiler. Die dritte Variante funktioniert. Nun würde ich diesen Wert 3000 MB in Bytes aber gerne als Konstante speichern. Geht das irgendwie?

maxk


Moderiert von user profile iconTino: Topic aus Sonstiges verschoben am Mo 19.07.2004 um 13:35


Udontknow - Fr 16.07.04 13:13

Hallo!

In64 ist tatsächlich ein wenig anfällig und nicht sehr performant. Wenn du nicht mit viel grösseren Zahlen hantieren musst, nimm doch einfach Cardinal (Wertebereich 0 bis 4.294.967.295).

Edit: Alternativ kannst du ja eine Variable deklarieren und sie im Initialization-Bereich der Unit mit dem Wert belegen.

Cu,
Udontknow


maxk - Fr 16.07.04 13:26

Der Cardinal bringt leider den gleichen Fehler. Ich brauch den Wert nur in einer Funktion, aber es wäre eben schön gewesen, eine Konstante nutzen zu können.


Udontknow - Fr 16.07.04 13:29

Du hast recht! Merkwürdig.

Na dann nimm eben meinen Plan B. Aus Performance-Gründen würde ich dir zum Cardinal raten, wenn der ausreicht.

Cu,
Udontknow


sourcehunter - So 18.07.04 21:55

Es könnte sein, dass Delphi ansich solche Zahlen Ausdrücke zur berechnung, wie du sie benutzt hat nur als einen Integer benutzt, weil du ja warscheinlich ein 32-Bit-System hast und das halt mit 32-Bit-Registern arbeitet und da nun mal das da nicht reinpasst. unter Delphi ist ein 64-Bit großer Datentyp nur simuliert.

Bei der ausführung würde dein Code warscheinlich so aussehen:

Register:=3000;
Register:=Register*1024;
Register:=Register*1024; -> Overflow


Udontknow - So 18.07.04 21:59

Aber er hat doch bereits im ersten Posting gesagt, daß eben zur Laufzeit kein Overflow auftritt...

Cu,
Udontknow


UC-Chewie - Mo 19.07.04 09:32

Wahrscheinlich werden Ganzzahlkonstanten als Integer behandelt. Und da diese vorzeichenbehaftet sind, können sie etwa Zahlen bis 2,1 Mrd darstellen. Und 3 Mrd ist halt größer. Deshalb gibts den Overflow.


SvenAbeln - Mo 19.07.04 11:41

Hallo,

in der Delphi Hilfe steht es doch:
Zitat:

Generell gilt, dass arithmetische Operationen mit Integer-Werten einen Wert des Typs Integer zurückliefern, der in der aktuellen Implementation mit dem 32-Bit-Longint identisch ist. Operationen liefern nur dann einen Wert vom Typ Int64, wenn sie für einen oder mehrere Int64-Operanden ausgeführt werden. Aus diesem Grund ergibt der folgende Quelltext kein korrektes Resultat:

var
I: Integer;
J: Int64;
...
I := High(Integer);
J := I + 1;

Um in dieser Umgebung einen Rückgabewert vom Typ Int64 zu erhalten, muss für I eine Typumwandlung in Int64 ausgeführt werden:

...
J := Int64(I) + 1;



Wenn du also einen Teil der Berechnung als Int64 definierst klappt es.


Delphi-Quelltext
1:
const Max=Int64(3000*1024)*1024;                    


maxk - Mo 19.07.04 12:46

Dort wo die Logik aufhört, scheint die Programmierung anzufangen :wink:
Aber danke, jetzt ist es so, wie ich's mir vorgestellt habe.


SvenAbeln - Mo 19.07.04 12:51

Da ist schon Logik dahinter:

Denn bei
Integer*Integer*Integer
kann der Compiler ja nicht erkennen das dieses Ergebnis zu groß wird.

aber bei
Int64 * Integer
kann er erkennen das mit Int64 gerechnet werden muß.

Gruß


maxk - Mo 19.07.04 12:54

Aber wenn ich ihm schon viaconst Max:Int64=... mit auf den Weg gebe, worum es sich handelt.. tz tz tz


Alibi - Mo 19.07.04 13:38

Klappt folgendes als Workaround:
Du gibst dir die Zahl in nem Edit aus, einmal Str+C kopieren und im Editor das ganze mit Str+V einfügen?


maxk - Mo 19.07.04 14:18


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
const Max1=3145728000;
      Max2:Int64=3145728000;
      Max3=Int64(3145728000);
var Max4:Int64;
begin
 Max4:=3145728000;
Alle 4 Möglichkeiten funktionieren.