Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Zwei Versionen über „for“ vergleichen (https://www.delphipraxis.net/125861-zwei-versionen-ueber-%84%93-vergleichen.html)

xZise 13. Dez 2008 11:24


Zwei Versionen über „for“ vergleichen
 
Hallo ihr,

zur Zeit vergleiche ich zwei Versionen folgendermaßen:
Delphi-Quellcode:
  if NewMajor <= Major then
  begin
    if NewMinor <= Minor then
    begin
      if NewRelease <= Release then
      begin
        if NewBuild <= Build then
        begin
          FNewVersion := false;
        end else
          FNewVersion := true;
      end else
        FNewVersion := true;
    end else
      FNewVersion := true;
  end else
    FNewVersion := true;
Wie kann ich das nun in eine Schleife umwandeln, wenn man statt 8 separate Variablen zwei eindimensionale Array hat?

Zur Zeit sieht es so aus:
Delphi-Quellcode:
  Result := true;
  for i := 0 to High(oldVersion) do
  begin
    if newVersion[i] < oldVersion[i] then
      Result := false;
  end;
Aber dort gibt es das Problem, dass das Ergebnis wahr wird, wenn die Versionen identisch sind. In diesem Falle, hätte ich aber gerne ein negatives Ergebnis (s.o.).

MfG
xZise

DeddyH 13. Dez 2008 11:59

Re: Zwei Versionen über „for“ vergleichen
 
Könnte das nicht so funktionieren (ungetestet)?
Delphi-Quellcode:
Result := false;
i := 0;
while (i < Length(oldVersion)) and not Result do
  begin
    case Sign(newVersion[i] - oldVersion[i]) of
      -1: break;         //newVersion ist älter -> raus hier
       1: Result := true; //newVersion ist neuer
    end;
    inc(i);
  end;

SirThornberry 13. Dez 2008 12:10

Re: Zwei Versionen über &#8222;for&#8220; vergleiche
 
ich würde es so machen:
Delphi-Quellcode:
var
  i: Integer;
  len: Integer;
begin
  i := 0;
  len := length(old_version);
  while (i < len) and (old_version[i] = new_version[i]) do
    inc(i);
  result := (i = len);

DeddyH 13. Dez 2008 12:29

Re: Zwei Versionen über „for“ vergleichen
 
Und was machst Du, wenn die "alte" Version neuer ist?

inherited 13. Dez 2008 12:43

Re: Zwei Versionen über „for“ vergleichen
 
warum packst du die Versionsnummern nicht in einen 32Bit-Int und schaust ob deine Versionsnummer kleiner oder gleich der anderen ist?

DeddyH 13. Dez 2008 12:45

Re: Zwei Versionen über „for“ vergleichen
 
Dann dürfen die einzelnen Array-Elemente nicht größer als 255 sein (wird wohl auch so sein, aber ich wollte mal darauf hinweisen :mrgreen:).

inherited 13. Dez 2008 12:47

Re: Zwei Versionen über „for“ vergleichen
 
Das Programm will ich sehen, das bei Version 255 ist :mrgreen:

SirThornberry 13. Dez 2008 13:20

Re: Zwei Versionen über &#8222;for&#8220; vergleiche
 
ups, hab gedacht es geht nur um unterschiedlichkeit - wieder die hälfte ni gelesen.

Uwe Raabe 13. Dez 2008 13:52

Re: Zwei Versionen über „for“ vergleichen
 
Zitat:

Zitat von DeddyH
Dann dürfen die einzelnen Array-Elemente nicht größer als 255 sein (wird wohl auch so sein, aber ich wollte mal darauf hinweisen :mrgreen:).

Man kann das Ganze auch in einen Int64 packen, dann stehen 4 mal 16 Bit zur Verfügung...

DeddyH 13. Dez 2008 14:06

Re: Zwei Versionen über „for“ vergleichen
 
Naja, letztendlich muss das der TE entscheiden ;)

Hawkeye219 13. Dez 2008 14:06

Re: Zwei Versionen über „for“ vergleichen
 
Hallo,

Zitat:

Zitat von Uwe Raabe
Man kann das Ganze auch in einen Int64 packen, dann stehen 4 mal 16 Bit zur Verfügung...

die VCL stellt sogar einen passenden Typ dafür bereit: Delphi-Referenz durchsuchenInt64Rec aus der Unit SysUtils.

Delphi-Quellcode:
var
  V1, V2 : Int64Rec;
begin
  V1.Words[0] := 0; // Buildnummer
  V1.Words[1] := 0; // Revisionsnummer
  V1.Words[2] := 0; // Nebenversionsnummer
  V1.Words[3] := 3; // Hauptversionsnummer

  V2.Words[0] := 1;
  V2.Words[1] := 0;
  V2.Words[2] := 0;
  V2.Words[3] := 2;

  if (Int64(V1) <= Int64(V2)) then
    ShowMessage ('V1 ist kleiner oder gleich V2');
Gruß Hawkeye

Apollonius 13. Dez 2008 14:15

Re: Zwei Versionen über „for“ vergleichen
 
Die Buildnummer Hauptversionsnummer sollte dann allerdings nicht größer als High(Smallint) sein, sonst wird der Int64 negativ.

xZise 13. Dez 2008 14:47

Re: Zwei Versionen über „for“ vergleichen
 
Zitat:

Zitat von inherited
Das Programm will ich sehen, das bei Version 255 ist :mrgreen:

Naja Version 255.X.Y.Z ist wirklich unrealistisch. Aber ich würde sagen dass X.Y.Z.255 relatistisch ist (wenn man z.B. das Datum da unterbringt oder so).

An Int (32 bit) dachte ich auch schon, aber dann muss man davon ausgehen, dass sie bei 255 "überläuft". Auch dachte ich, man müsse die if-Konstruktion eigentlich so ganz gut umsetzen können.

Wobei folgendes da ziemlich gut klingt:
Zitat:

Zitat von DeddyH
Könnte das nicht so funktionieren (ungetestet)?
Delphi-Quellcode:
Result := false;
i := 0;
while (i < Length(oldVersion)) and not Result do
  begin
    case Sign(newVersion[i] - oldVersion[i]) of
      -1: break;         //newVersion ist älter -> raus hier
       1: Result := true; //newVersion ist neuer
    end;
    inc(i);
  end;

MfG
xZise

Hawkeye219 13. Dez 2008 14:59

Re: Zwei Versionen über „for“ vergleichen
 
Hallo Philip,

Zitat:

Zitat von Apollonius
Die Buildnummer sollte dann allerdings nicht größer als High(Smallint) sein, sonst wird der Int64 negativ.

Das Vorzeichen steckt auf Rechnern mit einer Intel-CPU in der Hauptversionsnummer (Words[3], Little-Endian).

Gruß Hawkeye

Apollonius 13. Dez 2008 15:02

Re: Zwei Versionen über „for“ vergleichen
 
:oops: Das ist mir eigentlich bekant. Gut, dass du mitdenkst.

himitsu 13. Dez 2008 23:26

Re: Zwei Versionen über „for“ vergleichen
 
@Hawkeye219: if UInt64(V1) <= UInt64(V2) then :angel:


PS: bei FNewVersion hätt ich gedacht, daß dieses True ist, wenn NewXYZ > XYZ wird und nicht bei <= :gruebel:
also insgesammt glaub ich, stümmt was bei der anfänglich genannten IF-Verschachtelung nicht
Delphi-Quellcode:
if NewMajor < Major then
  begin
    if (NewMajor = Major) and (NewMinor < Minor) then
    begin
      if (NewMinor = Minor) and (NewRelease < Release) then
      begin
        if (NewRelease = Release) and (NewBuild < Build) then
        begin
          FNewVersion := false;
        end else
          FNewVersion := true;
      end else
        FNewVersion := true;
    end else
      FNewVersion := true;
  end else
    FNewVersion := true;
oder seh ich das grad irgendwie falsch?

gekürzt:
Delphi-Quellcode:
isNewVersion := (NewMajor > Major) or
  ((NewMajor = Major) and ((NewMinor > Minor) or
  ((NewMinor = Minor) and ((NewRelease > Release) or
  ((NewRelease = Release) and (NewBuild > Build))))));


Selber nutze ich auch gern Records, welche sich dann auch mal ganz leicht nach LongWord, bzw. LargeInt/UInt64 casten lassen:

Delphi-Quellcode:
Type TSmallVersion = packed Record
    Build:       Word;
    Minor, Major: Byte;
  End;

  TVersion = packed Record
    Build, Release: Word;
    Minor, Major:  Word;
  End;
Oder wie wäre es mal mit den neuen Funktionalitäten von Delphi?
und dann einfach nur noch
Delphi-Quellcode:
Var NewVersion, Version: TVersion;

...
If NewVersion <= Version Then ...
Delphi-Quellcode:
Type TSmallVersion = packed Record
    Build:       Word;
    Minor, Major: Byte;

    Class Operator Implicit(Rec:  TSmallVersion): LongWord;
    Class Operator Implicit(Value: LongWord): TSmallVersion;
    Class Operator Implicit(Rec:  TSmallVersion): String;
    Class Operator Implicit(Value: String): TSmallVersion;

    Class Operator Explicit(Rec:  TSmallVersion): LongWord;
    Class Operator Explicit(Value: LongWord): TSmallVersion;
    Class Operator Explicit(Rec:  TSmallVersion): String;
    Class Operator Explicit(Value: String): TSmallVersion;

    Class Operator Equal            (Oper1, Oper2: TSmallVersion): Boolean;
    Class Operator NotEqual         (Oper1, Oper2: TSmallVersion): Boolean;
    Class Operator LessThan         (Oper1, Oper2: TSmallVersion): Boolean;
    Class Operator LessThanOrEqual  (Oper1, Oper2: TSmallVersion): Boolean;
    Class Operator GreaterThan      (Oper1, Oper2: TSmallVersion): Boolean;
    Class Operator GreaterThanOrEqual(Oper1, Oper2: TSmallVersion): Boolean;

    Class Operator Add      (Oper1, Oper2: TSmallVersion): TSmallVersion;
    Class Operator Subtract (Oper1, Oper2: TSmallVersion): TSmallVersion;
    Class Operator BitwiseAnd(Oper1, Oper2: TSmallVersion): TSmallVersion;
    Class Operator BitwiseOr (Oper1, Oper2: TSmallVersion): TSmallVersion;
  End;

  TVersion = packed Record
    Build, Release: Word;
    Minor, Major:  Word;

    Class Operator Implicit(Rec:  TSmallVersion): UInt64;
    Class Operator Implicit(Value: LongWord): TSmallVersion;
    Class Operator Implicit(Rec:  TSmallVersion): String;
    Class Operator Implicit(Value: String): TSmallVersion;

    Class Operator Explicit(Rec:  TSmallVersion): UInt64;
    Class Operator Explicit(Value: UInt64): TSmallVersion;
    Class Operator Explicit(Rec:  TSmallVersion): String;
    Class Operator Explicit(Value: String): TSmallVersion;

    Class Operator Equal            (Oper1, Oper2: TSmallVersion): Boolean;
    Class Operator NotEqual         (Oper1, Oper2: TSmallVersion): Boolean;
    Class Operator LessThan         (Oper1, Oper2: TSmallVersion): Boolean;
    Class Operator LessThanOrEqual  (Oper1, Oper2: TSmallVersion): Boolean;
    Class Operator GreaterThan      (Oper1, Oper2: TSmallVersion): Boolean;
    Class Operator GreaterThanOrEqual(Oper1, Oper2: TSmallVersion): Boolean;

    Class Operator Add      (Oper1, Oper2: TSmallVersion): TSmallVersion;
    Class Operator Subtract (Oper1, Oper2: TSmallVersion): TSmallVersion;
    Class Operator BitwiseAnd(Oper1, Oper2: TSmallVersion): TSmallVersion;
    Class Operator BitwiseOr (Oper1, Oper2: TSmallVersion): TSmallVersion;
  End;


// die Definitionen der Funktionen hab ich mir erstmal gesparrt

xZise 14. Dez 2008 10:40

Re: Zwei Versionen über „for“ vergleichen
 
Zitat:

Zitat von himitsu
[...]
also insgesammt glaub ich, stümmt was bei der anfänglich genannten IF-Verschachtelung nicht[,...]

Doch doch: So wie ich es anfangs genannt habe passt das.

Wenn die Hauptversionsnummer größer ist, springt er ins else -> Result := true:
Delphi-Quellcode:
if NewMajor <= Major then
begin
  [...]
end else
  FNewVersion := true;
Ansonsten macht er das mit der Nebenversionsnummer, der Releasenummer oder der Buildnummer.

MfG
xZise

himitsu 14. Dez 2008 12:24

Re: Zwei Versionen über „for“ vergleichen
 
Zitat:

Zitat von xZise
Doch doch: So wie ich es anfangs genannt habe passt das.

Wenn die Hauptversionsnummer größer ist, springt er ins else -> Result := true:

eben nicht richtig :warn:

Delphi-Quellcode:
// New    = 3.9.0.0
// Current = 4.8.0.0

if NewMajor{3} <= Major{4} {=true} then
  begin
    if NewMinor{9} <= Minor{8} {=false} then
    begin
      ...
    end else
      FNewVersion := true; {das Ergebnis}
  end else
    FNewVersion := true;
hiernach wäre die 4.8 kleiner als 3.9, da 8 < 9

Der nächste Versionsteil darf nur geprüft werden, wenn die vorherigen Teile gleich sind.

inherited 14. Dez 2008 12:43

Re: Zwei Versionen über „for“ vergleichen
 
Ich mache das mit Versionen so:
Delphi-Quellcode:
  TVersion = packed record
    case Integer of
      0: (AsInt: Cardinal;);
      1: (AsArray: Array[0..3] of Byte;);
      2: (Major: Byte; Minor: Byte; Release: Byte; Build: Byte;);
  end;

xZise 14. Dez 2008 12:55

Re: Zwei Versionen über „for“ vergleichen
 
Moin himitsu,
Stimmt :) Aber deine Funktion ergibt auch "wahr", da Major != NewMajor ist.

Zitat:

Zitat von himitsu
[...]
Delphi-Quellcode:
if NewMajor {3} < Major {4} {true} then
begin
  if (NewMajor {3} = Major {4} {false}) and (NewMinor &lt; Minor) then
  begin
    if (NewMinor = Minor) and (NewRelease &lt; Release) then
    begin
      if (NewRelease = Release) and (NewBuild &lt; Build) then
      begin
        FNewVersion := false;
      end else
        FNewVersion := true;
    end else
      FNewVersion := true;
  end else
    FNewVersion := true;
end else
  FNewVersion := true;

Um genau zu sein, ist die Überprüfung ob die Werte gleich sind obsolet, da sie eh nie durchkommen würden (wobei dadurch das nicht mehr gehen würde).

Mein Vorschlag:
Delphi-Quellcode:
FNewVersion := false;
if NewMajor = Major then
begin
  if NewMinor = Minor then
  begin
    if NewRelease = Release then
    begin
      if NewBuild > Build then
      begin
        FNewVersion := true;
      end;
    end
    else if NewRelease > Release then
      FNewVersion := true;
  end
  else if NewMinor > Minor then
    FNewVersion := true;
end
else if NewMajor > Major then
  FNewVersion := true;
Zu Nikolai: Wie machst du den Vergleich?
Delphi-Quellcode:
var
  Ver, NewVer : TVersion;
begin
  if Ver... < NewVer... then
    FNewVersion := true
  else
    FNewVersion := false;
end;
MfG
xZise

inherited 14. Dez 2008 12:59

Re: Zwei Versionen über „for“ vergleichen
 
Einfach so:
Delphi-Quellcode:
IsNewVersion := NewVersion.AsCardinal > OldVersion.AsCardinal;

himitsu 14. Dez 2008 13:36

Re: Zwei Versionen über „for“ vergleichen
 
@inherited: sicher, daß du das so machst?

wir leben in einer BigEndian-Umgebung

Delphi-Quellcode:
2: (Build: Byte; Release: Byte; Minor: Byte; Major: Byte);
also der größte Wert zuletzt und hier ist Major das Größte

Hawkeye219 14. Dez 2008 13:57

Re: Zwei Versionen über „for“ vergleichen
 
Hallo Fabian,

ich habe das Gefühl, du liest die Antworten auf deine Fragen nicht sorgfältig genug: klick.

Da du mit Turbo Delphi arbeitest, solltest du noch die Ergänzung von himitsu zu Beginn des Beitrags #16 berücksichtigen.

@himitsu
richtige Idee - falsche Umgebung ;-)

Gruß Hawkeye

inherited 14. Dez 2008 14:02

Re: Zwei Versionen über „for“ vergleichen
 
Mein Dual-Corchen sagt, dass er LittleEndian ist ;)
Aber du hast recht, da ich Plattformunabhängig arbeite, sollte das in Compiler-Schalter.

himitsu 14. Dez 2008 15:13

Re: Zwei Versionen über „for“ vergleichen
 
falsche Umgebung?
Delphi/Windows ist doch BigEndian :gruebel:

ok, da inherited wohl in Linux? arbeitet, könnte es bei ihm zutreffen :stupid:


wie konnte man auch nur LittleEndian erfinden ... für TypeCasts ist BigEndian doch viel praktischer ^^

BUG 14. Dez 2008 15:25

Re: Zwei Versionen über „for“ vergleichen
 
Zitat:

Zitat von himitsu
falsche Umgebung?
Delphi/Windows ist doch BigEndian :gruebel:

:shock: Bist du sonst mit Java unterwegs? Ansonsten wirst du bei PCs AFAIK nur LittleEndian finden!
http://de.wikipedia.org/wiki/Endianness#Little

MfG,
Bug

himitsu 14. Dez 2008 16:07

Re: Zwei Versionen über „for“ vergleichen
 
Delphi-Quellcode:
var t: record
  case integer of
    0: (B1, B2, B3, B4: Byte);
    1: (L: LongWord);
end;

v.L := $12345678;
Edit1.Text := Format('$12345678 = L:$%x = B1:$%x B2:$%x B3:$%x B4:$%x',
  [V.L, V.B1, V.B2, V.B3, V.B4]);
Code:
$12345678 = L:$12345678 = B1:$78 B2:$56 B3:$34 B4:$12
letzes Byte ist das Höchstwertige

die Notation im Quelltext ist zwar LittleEndian, aber im Speicher ist es BigEndian


kann sein, das es auf Byteebene, also bei den einzelnen Bits anders aussieht und es dort wirklich LittleEndian ist, aber das läßt sich nicht so leicht prüfen.

Apollonius 14. Dez 2008 16:25

Re: Zwei Versionen über „for“ vergleichen
 
Himitsu, Little Endian heißt, dass das niederwertigste Byte an der niedrigsten Adresse liegt, und genau das ist hier der Fall.

xZise 14. Dez 2008 16:51

Re: Zwei Versionen über „for“ vergleichen
 
Zitat:

Zitat von Hawkeye219
Hallo Fabian,

ich habe das Gefühl, du liest die Antworten auf deine Fragen nicht sorgfältig genug: klick.

Tut mir Leid das ich deine Lösung ignoriert habe, aber eigentlich wollte ich gucken, was für Lösungen zu Tage treten, die keine solche Beschränkungen haben, wobei 16 bit natürlich viel Raum bietet. Ich denke dann werde ich es wohl doch so machen.

Zitat:

Zitat von Hawkeye219
Da du mit Turbo Delphi arbeitest, solltest du noch die Ergänzung von himitsu zu Beginn des Beitrags #16 berücksichtigen.

Und welchen meinst du? Dass der Vergleichsoperator ohne dem Gleichheitszeichen vorhanden sein muss?

MfG
xZise

himitsu 14. Dez 2008 17:13

Re: Zwei Versionen über „for“ vergleichen
 
wohl doch zu wenig geschlafen :wall:

Big-Endian > Großes Ende > und irgendwie war ih grad, laut der Übersetzung, der irrtümlichen Meinung das große zu letzt, also an höchster Stelle

na Gut, dann bleibt dieses aber dennoch in Windows so richtiger (Major als Letztes und nicht als Erstes)
Delphi-Quellcode:
2: (Build: Byte; Release: Byte; Minor: Byte; Major: Byte);

xZise 22. Dez 2008 14:35

Re: Zwei Versionen über „for“ vergleichen
 
Hallo,
Ich bins nochmal, weil er meint, eine neuere Version wäre älter:
Code:
FLocalVersionNumber := (327681, 131075, (327681, 131075), (1, 5, 3, 2), (1, 0, 5, 0, 3, 0, 2, 0))
FRemoteVersionNumber := (393217, 5, (393217, 5), (1, 6, 5, 0), (1, 0, 6, 0, 5, 0, 0, 0))
Delphi-Quellcode:
FNewVersion := Int64(FLocalVersionNumber) < Int64(FRemoteVersionNumber);
Ergebnis: FNewVersion soll false sein? Oder stimmt da was mit den Vergleichsoperator nicht?

MfG
xZise

Hawkeye219 22. Dez 2008 15:08

Re: Zwei Versionen über „for“ vergleichen
 
Fabian, ich möchte dich noch einmal auf Beitrag #11 verweisen - achte besonders auf die Kommentare.

Gruß Hawkeye

xZise 22. Dez 2008 15:15

Re: Zwei Versionen über „for“ vergleichen
 
Du meinst, dass die Hauptversionsnummer nicht größer als SmallInt sein soll? Ist es doch auch gar nicht.

Und ansonsten weiß ich gerade nicht, welche Kommentare du sonst meinst?

Öhm ... Seit wann isses denn genau andersherum (Die Reihenfolge der Words)?! :mrgreen: Und dann ist ja V2 älter als V1... Also auch den Operator umdrehen. :stupid:

MfG
xZise

himitsu 24. Dez 2008 11:05

Re: Zwei Versionen über „for“ vergleichen
 
Also wenn es an dem Int64 liegt, dann hilft ein einfaches Umdrehen des Operators nicht viel, denn dann müßtest du noch 'ne Vorzeichenkontrolle einbauen und dann je nach Vorzeichen anderes vergleichen ... oder halt UInt64 verwenden.

Oder doch solche Records wie in #16 beschrieben verwenden

xZise 24. Dez 2008 12:02

Re: Zwei Versionen über „for“ vergleichen
 
Zitat:

Zitat von himitsu
[...] oder halt UInt64 verwenden.[...]

Genau ;) das geht am schnellsten. Und bisher sind nach der Fehlerbehebung keine fehlerhaften Versionen aufgetaucht.

MfG
xZise


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