Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Inkompatible Datentypen in Procedures bei Arrays mit Double bzw. Extended (https://www.delphipraxis.net/209803-inkompatible-datentypen-procedures-bei-arrays-mit-double-bzw-extended.html)

enigma 25. Jan 2022 09:28

Inkompatible Datentypen in Procedures bei Arrays mit Double bzw. Extended
 
Hallo zusammen,

ich habe ein kleines Verständnisproblem bei der Kompatibilität der Datentypen
bei den Parametern:

Und zwar liegen in meinem Programm folgende Procedures vor:
Delphi-Quellcode:
procedure procExtended(AExt: Extended); //2022-01-24
begin
  ShowMessage('procExtended');
end;

procedure procDouble(ADouble: Double); //2022-01-24
begin
  ShowMessage('procDouble');
end;

procedure procArrDouble(AArrDouble: Array of Double); //2022-01-24
begin
  ShowMessage('procArrDouble');
end;

procedure procArrExtended(AArrExt: Array of Extended); //2022-01-25
begin
  ShowMessage('procArrExtended');
end;
Die Datenlage ist folgende:
Delphi-Quellcode:
  varDouble := 1.2;
  varExt := 7.3;
  arrDouble: array[0..2] of Double = (1.1, 2.2, 3.3);
  arrExt: array[0..2] of Double = (1.0, 2.0, 3.0);
Beim Aufrufen der Procedures klappt es mit den Datentypen bei folgendem:
Delphi-Quellcode:
  procExtended(varDouble);
  procDouble(varExt);
Bei den Arrays kommt aber die Meldung "Inkompatible Typen":
Delphi-Quellcode:
  procArrExtended(arrDouble);
  procArrDouble(arrExt);
Ich freue mich über jeden Hinweis

KodeZwerg 25. Jan 2022 09:32

AW: Inkompatible Datentypen in Procedures bei Arrays mit Double bzw. Extended
 
definiere deine array typen außerhalb, in der proc nimmst du dann diese definition. sollte funktionieren.

falls das unverständlich war ->
Delphi-Quellcode:
type
  TMyArr: Array of WasAuchImmer;


...


procedure Tada(AArr: TMyArr);

enigma 25. Jan 2022 09:42

AW: Inkompatible Datentypen in Procedures bei Arrays mit Double bzw. Extended
 
Hallo KodeZwerg,

danke für deinen Tipp mit der externen Typdefinition ;-)
Ich brauche aber keine speziellen Typen, sondern einfach
Array of Double bzw. Array of Extended.
Meine procedure soll beide, also Double und Extended akzeptieren,
was ja bei normalen Parametern klappt.

Was meinst du zu meiner Aussage?

KodeZwerg 25. Jan 2022 09:52

AW: Inkompatible Datentypen in Procedures bei Arrays mit Double bzw. Extended
 
Ich meine das es nur so funktionieren kann.

Delphi-Quellcode:
type
  TExtArr: Array of Extended;
  TDblArr: Array of Double;

...


procedure ExtArr(AArr: TExtArr);
begin
end;

procedure DblArr(AArr: TDblArr);
begin
end;

...

var
  MeinExt: TExtArr;
  MeinDbl: TDblArr;
begin
  SetLength(MeinExt, 1);
  SetLength(MeinDbl, 1);
  MeinExt[0] := 0.0;
  MeinDbl[0] := 0.0;
  ExtArr(MeinExt);
  DblArr(MeinDbl);

Andreas13 25. Jan 2022 10:01

AW: Inkompatible Datentypen in Procedures bei Arrays mit Double bzw. Extended
 
Hallo Enigma,
als Ergänzung zur korrekten Lösung von KodeZwerg nur so viel: Für den strengen Delphi-Compiler sind zwei Typendeklarationen nicht dann gleich, wenn sie auf die gleiche Art deklariert worden sind, sondern nur dann, wenn sie denselben Typen haben. Und das geht nur über eine benannte Typen-Deklaration, die Du verwendest. Mein Tipp dazu: Lege Dir eine globale Unit mit oft verwendeten Typendeklarationen, die Du als eigene Daten-Typen konsequent verwendest.
Beispiel:

Delphi-Quellcode:
Unit My_Types;

interface

uses
 System.Types;


Type
  TDynDoubleVektor     = System.Types.TDoubleDynArray; // oder: TArray<Double>;
  TDynExtendedVektor   = TArray<Extended>;

  TDynIntegerVektor    = System.Types.TIntegerDynArray; // oder: TArray<Integer>;
  TDynStringVektor     = System.Types.TStringDynArray; // oder: TArray<String>;
  TDynPAnsiCharVektor  = TArray<PAnsiChar>;

usw.

Implementation

Begin

End.
Gruß, Andreas

Blup 25. Jan 2022 10:01

AW: Inkompatible Datentypen in Procedures bei Arrays mit Double bzw. Extended
 
Eine Type-Deklaration deklariert ein dynamisches Array.
Wird ein ein Parameter von diesem Typ übergeben, so ist der Parameter in Wirklichkeit ein Zeiger auf das ursprüngliche Array.
Da gibt es keine Typumwandlung der Elemente.
Die Direktive "overload" ermöglicht Procedure mit gleichem Namen mit unterschiedlichen Parametern.

Eine direkte Array-Deklaration als Parameter deklariert eine sogenanntes "offenes Array".
Delphi-Quellcode:
procedure procArrDouble(const AArrDouble: Array of Double);


procedure Test;
var
  a: Double;
  b: Extendet;
  c: Integer;
begin
  procArrDouble([a, b, c]);
end;
Hier wird jeder einzelne Parameter in den Zieltyp umgewandelt und in ein offenes Array gepackt.

Andreas13 25. Jan 2022 10:12

AW: Inkompatible Datentypen in Procedures bei Arrays mit Double bzw. Extended
 
Von der Verwendung von "offenen Arrays" möchte ich warnen: Dem Vorteil, daß man mit derselben Routine sowohl statische (1-basierte Zählung), wie auch dynamische Arrays (0-basierte Zählung) bearbeiten lassen, steht der gravierende Nachteil entgegen, daß z.B. das 5-te Element in beiden Fällen verschiedene Inhalte bezeichnet. Damit kann man bei direktem Zugriff auf ein bestimmtes Element ziemlich schnell durcheinanderkommen.
Gruß, Andreas

bcvs 25. Jan 2022 10:13

AW: Inkompatible Datentypen in Procedures bei Arrays mit Double bzw. Extended
 
Zitat:

Zitat von enigma (Beitrag 1501147)
Meine procedure soll beide, also Double und Extended akzeptieren,
was ja bei normalen Parametern klappt.

Ich denke, das ist mit Arrays nicht möglich. Bei der Übergabe von Einzelparametern baut der Compiler eine Typumwandlung ein, sofern die Parameter zuweisungskompatibel sind. Da bei Arrays aber nur Zeiger übergeben werden, funktioniert das nicht mit der Typumwandlung.

Andreas13 25. Jan 2022 10:16

AW: Inkompatible Datentypen in Procedures bei Arrays mit Double bzw. Extended
 
Zitat:

Zitat von bcvs (Beitrag 1501154)
Zitat:

Zitat von enigma (Beitrag 1501147)
Meine procedure soll beide, also Double und Extended akzeptieren,
was ja bei normalen Parametern klappt.

Ich denke, das ist mit Arrays nicht möglich. Bei der Übergabe von Einzelparametern baut der Compiler eine Typumwandlung ein, sofern die Parameter zuweisungskompatibel sind. Da bei Arrays aber nur Zeiger übergeben werden, funktioniert das nicht mit der Typumwandlung.

Das geht nur, wie bereits gesagt, wenn man Overlaod verwendet: Selber Prozedurname, verschiedene Datentypen.
Andreas

KodeZwerg 25. Jan 2022 10:38

AW: Inkompatible Datentypen in Procedures bei Arrays mit Double bzw. Extended
 
Zitat:

Zitat von Andreas13 (Beitrag 1501155)
wenn man Overlaod verwendet: Selber Prozedurname, verschiedene Datentypen.

Beispiel:
Delphi-Quellcode:
type
  TExtArr = array of Extended;
  TDblArr = array of Double;

...

procedure AcceptMe(s: string); overload;
begin
end;
procedure AcceptMe(i: Integer); overload;
begin
end;
procedure AcceptMe(i64: Int64); overload;
begin
end;
procedure AcceptMe(AArr: TExtArr); overload;
begin
end;
procedure AcceptMe(AArr: TDblArr); overload;
begin
end;
nun kannst du "AcceptMe" mit vielen verschiedenen typen aufrufen und der name der procedure bleibt immer gleich.

Stevie 25. Jan 2022 10:56

AW: Inkompatible Datentypen in Procedures bei Arrays mit Double bzw. Extended
 
Zitat:

Zitat von enigma (Beitrag 1501145)
Delphi-Quellcode:
  varDouble := 1.2;
  varExt := 7.3;
  arrDouble: array[0..2] of Double = (1.1, 2.2, 3.3);
  arrExt: array[0..2] of Double = (1.0, 2.0, 3.0); // <--- !!!

Falscher Typ, oder?

Und nein, auch wenn Typ X auf Typ Y zuweisungskompatibel ist, ist ein Array von X nicht auf ein Array von Y zuweisungkompatibel.

himitsu 25. Jan 2022 13:22

AW: Inkompatible Datentypen in Procedures bei Arrays mit Double bzw. Extended
 
Extended soll man eh nicht verwenden, somit ist es egal.
Estended war eh niemals für die direkte Verwendung/Speicherung vorgesehn.

Und beim Überladen hast mit Extended außerhalb Windows (Android/iOS/OSX) wowieso Probleme, da es diesen Typ dort nicht gibt.
OK ihn gibt es, aber er ist dort intern ein Double und schon hast mit deiner Überladung ein kleines Problemchen.



Zitat:

Delphi-Quellcode:
type
  TExtArr = array of Extended;
  TDblArr = array of Double;

procedure AcceptMe(AArr: TExtArr); overload;
procedure AcceptMe(AArr: TDblArr); overload;

Hier hast ein Problem, dass es nur genau diesen Typen annimmt und nichts Anderes.

Es ist allgemein besser, hier einen Standardtypen zu nutzen, denn so kann man dieses Array nicht nur mit der eigenen, sondern auch mit fremden Funktionen nutzen.
Delphi-Quellcode:
type TDblArr = TArray<Double>; // oder TDoubleDynArray
procedure AcceptMe(AArr: TDblArr); overload;
oder als offenes Array deklarieren,
Delphi-Quellcode:
procedure AcceptMe(AArr: array of Double); overload;

denn sowas nimmt viele Arrays an, die aus irgendeinem Array von Double bestehen,
also direkt ein Konstanten-Array ala
Delphi-Quellcode:
[1.1, 2.2, 3.3]
übergeben oder andere Array-Typen aus Doubles
und sogar statische Arrays ala
Delphi-Quellcode:
array[0..15] of Double
(siehe Post #1).

Uwe Raabe 25. Jan 2022 15:30

AW: Inkompatible Datentypen in Procedures bei Arrays mit Double bzw. Extended
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

Zitat von himitsu (Beitrag 1501164)
OK ihn gibt es, aber er ist dort intern ein Double

Na ja, so ganz stimmt das aber auch nicht: https://docwiki.embarcadero.com/RADS...hi)#Real_Types

himitsu 25. Jan 2022 16:52

AW: Inkompatible Datentypen in Procedures bei Arrays mit Double bzw. Extended
 
Intern ist der Typ "Extended" entweder 10 Byte (Extended) oder 8 Byte (Double), je nach OS und Bitigkeit.

Wie groß der Typ nach außen ist, das hängt davon ab, wie, je nach OS, der Speicher aligned wird und wie der Compiler eingestellt wurde.
Da kann er 8 bis 16 Byte sein, oder auch garnicht existieren.
Delphi-Quellcode:
{$EXTENDEDCOMPATIBILITY ON}


Hmm, OK, das mit Linux hatte ich nicht mitbekommen,
aber da es Apple praktisch nur noch als 64 Bit gibt und man den 32 Bit-iOS-Simulator (Intel) vergessen kann,
bleiben ja nur noch Win32 und Linux übrig (auf x86 ... nicht auf ARM, falls es das jemals gibt).

Ich frag mich nur, wie Linux das eigentlich machen will? (der Typ OK, aber damit auch "schnell" rechnen .. nicht wie der emulierte Int64/UInt64 im Win32)
Das war doch ein Ding der FPU und Jene gibt es in der 64 Bit-CPU (Intel/AMD) nicht mehr, sowie nicht im ARM.


Offiziell Ursprünglich (außerhalb der Pascal/Delphi-Welt) war Extended eh nie zum Speichern vorgesehn, sondern vorwiegend nur für Zwischenschritte von Berechnungen.
Aber OK, falls C-Compiler den Typ nicht kennen, dann kann man ihn auch dort teilweise aktivieren.
"long double" (80-bit double extended format) im C++, bzw. double-double damals auf PowerPC.




Nja, wird eh Zeit, dass wir Float128 (quadruple precision) im Delphi bekommen, was uns im IEEE 754 versprochen wurde. :stupid:

Andreas13 25. Jan 2022 17:01

AW: Inkompatible Datentypen in Procedures bei Arrays mit Double bzw. Extended
 
Zitat:

Zitat von himitsu (Beitrag 1501177)
Nja, wird eh Zeit, dass wir Float128 (quadruple precision) im Delphi bekommen, was uns im IEEE 754 versprochen wurde. :stupid:

quadruple precision gibt's derzeit nur als externe Delphi-Bibliothek von Erik van Bilsenhttps://github.com/neslib/Neslib.MultiPrecision. Allerdings kennt die zugrundeliegende C++-Bibliothek noch kein +/- Unendlich und liefert bei manchen algebraischen Operationen anstelle von 0 (z.B. bei 1/Unendlich) noch sinnlose Fehlermeldungen. Habe bereits vor etlichen Monaten den Urheber der C++-Bibliothek auf https://www.davidhbailey.com/dhbsoftware/ um Korrektur gebeten, was auch versprochen wurde. Anscheinend ist aber das Problem komplexer als es scheint.
Gruß, Andreas

enigma 27. Jan 2022 08:31

AW: Inkompatible Datentypen in Procedures bei Arrays mit Double bzw. Extended
 
Vielen Dank für eure hilfreichen Tipps!
Auf overload bin ich inzwischen selbst gekommen ;-)


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