Einzelnen Beitrag anzeigen

Benutzerbild von sirius
sirius

Registriert seit: 3. Jan 2007
Ort: Dresden
3.443 Beiträge
 
Delphi 7 Enterprise
 
#38

Re: Mathe mit Strings (die deutsche StringMatheLib ._. )

  Alt 16. Jun 2009, 13:13
Ich habe mal folgende Ergänzung gemacht (für alle, die keine class operators nutzen können):
Delphi-Quellcode:
Unit StringMatheLib;
//ich tippe hier nur die Ergänzungen, alles andere von himi sollte man beibehalten

interface

uses Variants;


type

  TMatheVarData = packed record
    VType: TVarType;
    Reserved1, Reserved2, Reserved3: Word;
    Mathe: String; //Man könnte hier auch TMathe drin speichern und den String in die Klasse legen, wäre etwas elegenater und sicherer, da man mit der automatischen Verwaltung der Strings nicht kollidieren kann. Ich wollte nur grad die Klasse TMathe nicht umschreiben.
    Reserved4: LongInt;
  end;


  TMatheVariant=class(TCustomVariantType)
   public
    procedure BinaryOp(var Left: TVarData; const Right: TVarData; const Operator: TVarOp); override;
    procedure UnaryOp(var Right: TVarData; const Operator: TVarOp); override;
    function CompareOp(const Left, Right: TVarData; const Operator: TVarOp): Boolean; override;
    procedure Compare(const Left, Right: TVarData; var Relationship: TVarCompareResult); override;
    procedure Cast(var Dest: TVarData; const Source: TVarData); override;
    procedure CastTo(var Dest: TVarData; const Source: TVarData; const AVarType: TVarType); override;
    procedure Clear(var V: TVarData); override;
    procedure Copy(var Dest: TVarData; const Source: TVarData; const Indirect: Boolean); override;
    function IsClear(const V: TVarData): Boolean; override;
   protected
    function LeftPromotion(const V: TVarData; const Operator: TVarOp; out RequiredVarType: TVarType): Boolean; override;
    function RightPromotion(const V: TVarData; const Operator: TVarOp; out RequiredVarType: TVarType): Boolean; override;
  end;


  function VarMatheCreate:Variant; overload;
  function VarMatheCreate(const Init:string):Variant; overload;
  function VarMatheCreate(const Init:Integer):Variant; overload;

implementation


var TempMatheVariant:TMatheVariant=nil;
    Mathe:TMathe=nil;


function VarMatheCreate(const Init:string):Variant;
begin
  VarClear(Result);
  TMatheVarData(Result).VType:=TempMatheVariant.VarType;
  TMatheVarData(Result).Mathe:=Init;
end;
function VarMatheCreate:Variant;
begin
  result:=VarMatheCreate('0');
end;
function VarMatheCreate(const Init:Integer):Variant;
var s:string;
begin
  str(init,s);
  result:=VarMatheCreate(s);
end;




{ TMatheVariant }


procedure TMatheVariant.BinaryOp(var Left: TVarData; const Right: TVarData;
  const Operator: TVarOp);
var sRight:string;
begin
  if TMatheVarData(Left).VType<>TempMatheVariant.VarType then
    RaiseInvalidOp;
  if TMatheVarData(Right).VType=TempMatheVariant.VarType then
    sRight:=TMatheVarData(Right).Mathe
  else
    sRight:=VarToStr(Variant(Right));

  case Operator of
    opAdd:
      TMatheVarData(Left).Mathe:=Mathe.Summe(TMatheVarData(Left).Mathe,
                                             sRight);
    opSubtract:
      TMatheVarData(Left).Mathe:=Mathe.Differenz(TMatheVarData(Left).Mathe,
                                                 sRight);
    opMultiply:
      TMatheVarData(Left).Mathe:=Mathe.Produkt(TMatheVarData(Left).Mathe,
                                               sRight);
    opIntDivide:
      TMatheVarData(Left).Mathe:=Mathe.Quotient(TMatheVarData(Left).Mathe,
                                                sRight);
    opModulus:
      TMatheVarData(Left).Mathe:=Mathe.Modulo(TMatheVarData(Left).Mathe,
                                              sRight);
    else
      RaiseInvalidOp;
  end;
end;

procedure TMatheVariant.Cast(var Dest: TVarData; const Source: TVarData);
begin
  VarDataClear(Dest);
  fillchar(Dest,sizeof(dest),0);
  TMatheVarData(Dest).VType:=TempMatheVariant.VarType;
  if TMatheVarData(Source).VType=TempMatheVariant.VarType then
    TMatheVarData(Dest).Mathe:=TMatheVarData(Source).Mathe
  else
    TMatheVarData(Dest).Mathe:=VarToStr(Variant(Source));
end;

procedure TMatheVariant.CastTo(var Dest: TVarData; const Source: TVarData;
  const AVarType: TVarType);
var Temp:TVarData;
begin
  if TMatheVarData(Source).VType=TempMatheVariant.VarType then
  begin
    fillchar(temp,sizeof(temp),0);
    Temp.VType:=varstring;
    Temp.VString:=Pointer(TMatheVarData(Source).Mathe);
    VarDataCastTo(Dest,Temp,aVarType);
  end else
    inherited;
end;

procedure TMatheVariant.Clear(var V: TVarData);
begin
  if TMatheVarData(V).VType=TempMatheVariant.VarType then
  begin
    TMatheVarData(V).VType:=varEmpty;
    TMatheVarData(V).Mathe:='';
  end else
    inherited;
end;

procedure TMatheVariant.Compare(const Left, Right: TVarData;
  var Relationship: TVarCompareResult);
var sRight:string;
begin
  if TMatheVarData(Left).VType<>TempMatheVariant.VarType then
    RaiseInvalidOp;
  if TMatheVarData(Right).VType=TempMatheVariant.VarType then
    sRight:=TMatheVarData(Right).Mathe
  else
    sRight:=VarToStr(Variant(Right));

  case Mathe.Vergleich(TMatheVarData(Left).Mathe,sRight) of
    LessThanValue: RelationShip:=crLessThan;
    EqualsValue : RelationShip:=crEqual;
    GreaterThanValue : RelationShip:=crGreaterThan;
  end;
end;

function TMatheVariant.CompareOp(const Left, Right: TVarData;
  const Operator: TVarOp): Boolean;
var sRight:string;
    Art:TVergleich;
begin
  if TMatheVarData(Left).VType<>TempMatheVariant.VarType then
    RaiseInvalidOp;
  if TMatheVarData(Right).VType=TempMatheVariant.VarType then
    sRight:=TMatheVarData(Left).Mathe
  else
    sRight:=VarToStr(Variant(Right));

  Art:=vGleich;
  case Operator of
    opCmpNE:Art:=vUngleich;
    opCmpLT:Art:=vKleiner;
    opCmpLE:Art:=vKleinerGleich;
    opCmpGT:Art:=vGroesser;
    opCmpGE:Art:=vGroesserGleich;
  end;
  result:=Mathe.Vergleich(TMatheVarData(Left).Mathe,sRight,Art);

end;

procedure TMatheVariant.Copy(var Dest: TVarData; const Source: TVarData;
  const Indirect: Boolean);
begin
  if Indirect and VarDataIsByRef(Source) then
    VarDataCopyNoInd(Dest, Source)
  else
  begin
    TMatheVarData(Dest).VType:=TempMatheVariant.VarType;
    TMatheVarData(Dest).Mathe:=TMatheVarData(Source).Mathe;
  end;

end;

function TMatheVariant.IsClear(const V: TVarData): Boolean;
begin
  result:=TMatheVarData(V).Mathe='';
end;

function TMatheVariant.LeftPromotion(const V: TVarData;
  const Operator: TVarOp; out RequiredVarType: TVarType): Boolean;
begin
  result:=inherited LeftPromotion(V,Operator,RequiredVarType);
end;

function TMatheVariant.RightPromotion(const V: TVarData;
  const Operator: TVarOp; out RequiredVarType: TVarType): Boolean;
begin
  result:=inherited RightPromotion(V,Operator, RequiredVarType);
end;

procedure TMatheVariant.UnaryOp(var Right: TVarData;
  const Operator: TVarOp);
begin
  if Right.VType = VarType then
    case Operator of
      opNegate:
        Mathe.Negieren(TMatheVarData(Right).Mathe);
    else
      RaiseInvalidOp;
    end
  else
    RaiseInvalidOp;
end;

initialization

Mathe:=TMathe.Create;
TempMatheVariant:=TMatheVariant.Create;


finalization

TempMatheVariant.Free;
TempMatheVariant:=nil;
Mathe.Free;
Mathe:=nil;

End.
Damit geht dann auch folgendes (z.B. unter Delphi 7):
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var x,z:Variant;
begin
  x:=VarMatheCreate('1200000000000000000000000000'); //um eine Initialisierung kommt man nicht herum

  //aber dann:
  x:=x+'3';
  z:=x+1;
  z:=z*2;
  memo1.lines.add(-z);
end;
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.
  Mit Zitat antworten Zitat