Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   überlauf bei eigenem Zahlentyp (https://www.delphipraxis.net/130746-ueberlauf-bei-eigenem-zahlentyp.html)

TeronG 12. Mär 2009 14:15


überlauf bei eigenem Zahlentyp
 
Hi

Ich habe ein Ventil das die Stellung 1 bis 16 haben kann.
Nun hab ich mir einen eigenen Type definiert der von 1 .. 16 geht.
Nun dachte ich, daß wenn ich über 16 hinauskomme (überlauf) ich wieder bei 1 lande. (Wie bei Byte, Word, ...)
Nur leider klappt das nicht. Wenn ich meinem Type einen Wert über 16 zuweise meckert zwar Delphi (Bereichsüberschreitung) aber während der Laufzeit stört es nicht, wenn der Wert außerhalb des Bereiches liegt.

Delphi-Quellcode:
type
  TStellung = 1..16;

var
  vStellung : TStellung;
Meine Frage währe nun wie ich diesen "Überlaufeffekt" auch bei meinem Type mir bekomme?

Vorläufig habe ich das mal alles ausprogrammiert aber mit überlauf währe schöner. :)

sirius 12. Mär 2009 14:23

Re: überlauf bei eigenem Zahlentyp
 
Das bekommst du ohne eigene Prüfung nicht hin. Der Überlauf wird ja nicht vom Programm o.ä. erzeugt sondern ist hardwarebedingt von der CPU.
Prüpf doch einfach selber, oder schreib dir ne Klasse drumrum, wenn es wichtig ist.

himitsu 12. Mär 2009 14:51

Re: überlauf bei eigenem Zahlentyp
 
schalte mal die Bereichsprüfung an (siehe Projektoptionen)

Reinhard Kern 12. Mär 2009 15:05

Re: überlauf bei eigenem Zahlentyp
 
Zitat:

Zitat von TeronG
Hi

Ich habe ein Ventil das die Stellung 1 bis 16 haben kann.
Nun hab ich mir einen eigenen Type definiert der von 1 .. 16 geht.
Nun dachte ich, daß wenn ich über 16 hinauskomme (überlauf) ich wieder bei 1 lande. (Wie bei Byte, Word, ...)
...

Hallo,

dafür ist schon die Definition schlecht geeignet, bei 0..15 wäre es einfacher (du müsstest jedes Ergebnis einer Operation MOD 16 speichern). Ein Byte geht ja auch nicht von 1..256, sondern von 0..255.

Gruss Reinhard

TeronG 12. Mär 2009 15:11

Re: überlauf bei eigenem Zahlentyp
 
Zitat:

Zitat von himitsu
schalte mal die Bereichsprüfung an (siehe Projektoptionen)

So bekomme ich ja "nur" ne neue Fehlermeldung. (und die meide ich ja normalerweise ^^)
Ich könnte die natürlich abfangen und darauf reagieren aber da prüfe ich lieber vorher ob alles seine Richtigkeit hat. ^^

Zitat:

Zitat von sirius
Das bekommst du ohne eigene Prüfung nicht hin. Der Überlauf wird ja nicht vom Programm o.ä. erzeugt sondern ist hardwarebedingt von der CPU.

Schade sowas habe ich schon fast befürchtet :(
Zitat:

Zitat von sirius
Prüpf doch einfach selber, oder schreib dir ne Klasse drumrum, wenn es wichtig ist.

Ich prüfe es ja z.Z. eh schon selber und das Ding dreht sich auch brav von 16 (eins weiter) auf 1.
Das mit dem Überlauf währe hald eine "schönere"/flexiblere Lösung gewesen. Quasi so ne art Instant-Schleife ^^

Naja bleib ich hald bei Integer und meiner MPVStellungscheck-Function.

Dennoch danke für die Antworten :D

himitsu 12. Mär 2009 15:17

Re: überlauf bei eigenem Zahlentyp
 
du könntest dir notfalls einen kleinen Operator-Record erstellen (langsam mag ich diese Teile :mrgreen: ) und die Überlaufbehandluch da einbauen. :angel:

mr_emre_d 12. Mär 2009 17:37

Re: überlauf bei eigenem Zahlentyp
 
-- sorry

edit:

Delphi-Quellcode:
function RangeVal( Val, _Min, _Max: Integer ): Integer;
begin
  Result := Val;
  if ( Val < _Min ) or ( Val > _Max ) then
  begin
    if Val > _Max then
      Result := Val - _Max + _Min - 1;
    if Val < _Min then
      Result := _Max - ( _Min - Val - 1 );
    Result := RangeVal( Result, _Min, _Max );
  end;
end;

TeronG 13. Mär 2009 08:28

Re: überlauf bei eigenem Zahlentyp
 
Zitat:

Zitat von himitsu
du könntest dir notfalls einen kleinen Operator-Record erstellen (langsam mag ich diese Teile :mrgreen: ) und die Überlaufbehandluch da einbauen. :angel:

War das das Teil, daß Daniel in einen seiner Videos vorgestellt hatte? Hatte er im beispiel nicht 2 Strings addiert oder so? :gruebel:
Das währe natürlich auch eine Idee ^^

Zitat:

Zitat von mr_emre_d
Delphi-Quellcode:
function RangeVal( Val, _Min, _Max: Integer ): Integer;
begin
  Result := Val;
  if ( Val < _Min ) or ( Val > _Max ) then
  begin
    if Val &gt; _Max then
      Result := Val - _Max + _Min - 1;
    if Val &lt; _Min then
      Result := _Max - ( _Min - Val - 1 );
    Result := RangeVal( Result, _Min, _Max );
  end;
end;

hui nice
Ich habe z.Z. eine einfache IF abfrage. IF wert > Max then wert-Max ...
Da mein wert nur maximal 31 (2×max-1) annehmen kann reicht das eigentlich wollte das aber noch verbessern.
Dachte da an irgendwas mit while oder sowas wie Mod aber auf eine "einfache" Rekursion währ ich nie gekommen. Das geht dann auch bei Zahlen die nicht von 1(0)..X gehen :thumb:

himitsu 13. Mär 2009 09:30

Re: überlauf bei eigenem Zahlentyp
 
ich wollt nur nochmal dieses vorstellen ... von der Declaration etwas Overload,
aber in der Verwendung einfach (von Equal bis Subtract könnte man notfalls was weglassen, halt das, was nicht benötigt wird ... hier im Beispiel wird z.B. nur Implicit, Inc und Equal benötigt)
Delphi-Quellcode:
Type TStellung = 1..16;
  TStellungRec = Record
    Class Operator Implicit         (Value: TStellung):   TStellungRec;
    Class Operator Implicit         (Rec:  TStellungRec): TStellung;
    Class Operator Inc              (Rec:  TStellungRec): TStellungRec;
    Class Operator Dec              (Rec:  TStellungRec): TStellungRec;
    Class Operator Equal            (Oper1, Oper2: TStellungRec): Boolean;
    Class Operator NotEqual         (Oper1, Oper2: TStellungRec): Boolean;
    Class Operator LessThan         (Oper1, Oper2: TStellungRec): Boolean;
    Class Operator LessThanOrEqual  (Oper1, Oper2: TStellungRec): Boolean;
    Class Operator GreaterThan      (Oper1, Oper2: TStellungRec): Boolean;
    Class Operator GreaterThanOrEqual(Oper1, Oper2: TStellungRec): Boolean;
    Class Operator Add              (Oper1, Oper2: TStellungRec): TStellungRec;
    Class Operator Subtract         (Oper1, Oper2: TStellungRec): TStellungRec;
  Private
    Stellung: TStellung;
    Class Procedure RangeCheck      (Var Value: TStellung); Static;
  End;

Class Operator TStellungRec.Implicit(Value: TStellung): TStellungRec;
  Begin
    Result.Stellung := Value;
    RangeCheck(Result.Stellung);
  End;

Class Operator TStellungRec.Implicit(Rec: TStellungRec): TStellung;
  Begin
    Result := Rec.Stellung;
  End;

Class Operator TStellungRec.Inc(Rec: TStellungRec): TStellungRec;
  Begin
    Result.Stellung := Rec.Stellung;
    Inc(Result.Stellung);
    RangeCheck(Result.Stellung);
  End;

Class Operator TStellungRec.Dec(Rec: TStellungRec): TStellungRec;
  Begin
    Result.Stellung := Rec.Stellung;
    Dec(Result.Stellung);
    RangeCheck(Result.Stellung);
  End;

Class Operator TStellungRec.Equal(Oper1, Oper2: TStellungRec): Boolean;
  Begin
    Result := Oper1.Stellung = Oper2.Stellung;
  End;

Class Operator TStellungRec.NotEqual(Oper1, Oper2: TStellungRec): Boolean;
  Begin
    Result := Oper1.Stellung <> Oper2.Stellung;
  End;

Class Operator TStellungRec.LessThan(Oper1, Oper2: TStellungRec): Boolean;
  Begin
    Result := Oper1.Stellung < Oper2.Stellung;
  End;

Class Operator TStellungRec.LessThanOrEqual(Oper1, Oper2: TStellungRec): Boolean;
  Begin
    Result := Oper1.Stellung >= Oper2.Stellung;
  End;

Class Operator TStellungRec.GreaterThan(Oper1, Oper2: TStellungRec): Boolean;
  Begin
    Result := Oper1.Stellung > Oper2.Stellung;
  End;

Class Operator TStellungRec.GreaterThanOrEqual(Oper1, Oper2: TStellungRec): Boolean;
  Begin
    Result := Oper1.Stellung >= Oper2.Stellung;
  End;

Class Operator TStellungRec.Add(Oper1, Oper2: TStellungRec): TStellungRec;
  Begin
    Result := Oper1.Stellung + Oper2.Stellung;
    RangeCheck(Result.Stellung);
  End;

Class Operator TStellungRec.Subtract(Oper1, Oper2: TStellungRec): TStellungRec;
  Begin
    Result := Oper1.Stellung - Oper2.Stellung;
    RangeCheck(Result.Stellung);
  End;

Class Procedure TStellungRec.RangeCheck(Var Value: TStellung);
  Begin
    While Value < Low(TStellung) do Value := Value + (High(TStellung) - Low(TStellung) + 1);
    While Value > High(TStellung) do Value := Value - (High(TStellung) - Low(TStellung) + 1);
  End;
Delphi-Quellcode:
Var Stellung: TStellungRec;

Begin
  Stellung := 14;
  Inc(Stellung); // 15
  Inc(Stellung); // 16
  Inc(Stellung); // 1
  Inc(Stellung); // 2
  If Stellung = 1 Then ;
End.
hier ließen sich dann ahc so Sachen wie
Delphi-Quellcode:
Type TStellung = (a=1, b=2, d=4, z=26);
leicht lösen ... man muß dann nur die Berechnungen anpassen

TeronG 13. Mär 2009 10:03

Re: überlauf bei eigenem Zahlentyp
 
1.) jup das war das, dass ich meinte. (Aus dem Wolf-Produktion-Video)
2.) WOW:shock:
DAS nenne ich mal ausführlich! :thumb: *schwelg*
Danke für die ganze Mühe. :)

Eigentlich ja ne recht feine Sache.
Einmal ausprogrammiert lässt sich dann damit schön arbeiten und der (restliche? ^^) Quellcode bleibt übersichtlich und verständlich.


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:14 Uhr.
Seite 1 von 2  1 2      

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