Announcement

Collapse
No announcement yet.

Compilerfehler?

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Compilerfehler?

    Hallo,<br>
    in Delphi formuliere is folgendes:<br>
    var<br>
    t1,t2: 1..31;<br>
    m1,m2: 1..12;<br>
    j1,j2: word;<br>
    diff : word;<br>

    begin<br>
    {Einlesen 1. und 2. Datum im format TT MM JJ}<br>
    {ueber eine Maskedit fuer ein Datum}
    {gebe ich nun für Tag einen Wert über 31 ein, wird das ohne}<br>
    {weiteres akzeptiert. Gelten Teilbereichstypen in D4 nicht?}<br>
    end.<br>

    P.S.: Alle Optionen Bereichsüberprüfung etc. sind eingeschaltet<br>

    Bei Borland Pascal habe ich dagegen folgendes Problem:<br>

    Ich definiere die Daten wie oben und berechne nach Eingabe wie folgt:<br>
    Diff := (j2-j1)*360 + (m2-m1)*30 + t1-t2<br>

    Dabei erhalte ich einen Arithmetikueberlauf. Ist der Compiler nicht in<br>
    der Lage, ein Zwischenergebnis (hier evtl negativ) zwischenzuspeichern?<br>
    auch wenn dafür keine entsprechende Variable explizit zur Verfügung steht?<br>

    Fuer Hinweise waere ich dankbar<br>

    Thomas Müller

  • #2
    Hallo,
    <BR><BR>
    Dein erstes Problem liegt wahrscheinlich am „späten Binden“ der Typumwandlung StrToInt(MaskEdit1.Text), ohne die strenge Typprüfung (hier Bereich von ganzen Zahlen) durch den Compiler.
    <BR>
    Als Lösung möchte ich aber einen anderen Vorschlag machen. Du muß sowieso auch die Tageszahlen 30 und 29 prüfen. Dafür kannst Du einfach den „MaskEdit1.Text“ mit „StingToDate()“ oder die einzelnen Bestandteile Tag, Monat und Jahr mit „EncodeDate()“ in den Datentyp TDateTime umwandeln. Damit das alles gut läuft, muß die Exception abgefangen werden. Das Datum ist danach in jedem Fall ein gültiger Datumswert.
    <BR>
    <PRE>
    ...
    try
    //“1900“ nur, weil das Datum offenbar 2-stellig erfaßt werden soll (Y2K???).
    vDate1:= EncodeDate(1900+j1, m1, t1);
    except
    ShowMessage(‚Datum 1 falsch eingegeben.‘);
    Raise;
    end;
    try
    vDate2:= EncodeDate(1900+j2, m2, t2);
    except
    ShowMessage(‚Datum 2 falsch eingegeben.‘);
    Raise;
    end;
    //Datum wieder in die Bestandteile zerlegen.
    DecodeDate(vDate1, j1, m1, t1);
    DecodeDate(vDate2, j2, m2, t2);
    Diff := (j2-j1)*360 + (m2-m1)*30 + t1-t2;
    </PRE>
    <BR><BR>
    Das zweite Problem „Diff := (j2-j1)*360 + (m2-m1)*30 + t1-t2;“ läuft bei mir, ich bitte um ein Zahlenbeispiel!
    <BR><BR>
    Gruß Dir

    Comment


    • #3
      Hallo Dirk<p>,
      Danke für den Tip. Ich werde es testen.<p>
      Das andere (Tagesdiff.) läuft bei mir jetzt auch, weiss aber nicht, warum. Hast du es auch in BP 7.0 probiert oder in Delphi (da geht es nämlich schon immer.<p>

      Hier ein weiteres Beispiel für Probleme dieser Art in BP:<p>

      PROGRAM Numerische_Probleme;<p>
      USES<p>
      CRT;<p>

      {$Q-} {Versuch Überlaufprüfung off}<p>
      VAR<p>
      Int_A,<p>
      Int_B : INTEGER;<p>
      L_Int : LONGINT;<p>

      Byte_A,<p>
      Byte_B : BYTE;<p>
      Word_V : WORD;<p>

      Real_V : REAL;<p>
      I : INTEGER;<p>

      BEGIN<p>
      CLRSCR;<p>
      WRITELN('Probleme der Integeroperationen - DEMO NUMPROBL.PAS');<p>
      WRITELN;<p>

      WRITELN('Integerberechnungen');<p>
      Int_A:=16383;<p>
      Int_B:=2 ;<p>

      L_Int:=Int_A*Int_B; {ok, da Ergebnis im Bereich Integer liegt }<p>
      WRITELN(Int_A,' * ',Int_B,' = ',L_Int:10);<p>

      L_Int:=Int_A*Int_B+1; {ok, da im Bereich Integer}<p>
      WRITELN(Int_A,' * ',Int_B,' + 1 = ',L_Int:10);<p>

      L_Int:=Int_A*Int_B+2; {Einer der Operatoren läuft über - SHL - negative Zahl}<p>
      WRITELN(Int_A,' * ',Int_B,' + 2 = ',L_Int:10);<p>

      WRITELN('32768 + 1 = ',32768+1:10); { kein Problem bei numerischem Literal }<p>

      WRITELN;<p>
      WRITELN('Wordberechnungen');<p>
      Word_V:=65000;<p>
      L_Int := Word_V*2;<p>
      WRITELN('65000 * 2 = ',L_int:10);<p>

      WRITELN;<p>
      WRITE ('Demo SHL : ');<p>
      FOR I := 1 TO 8 DO WRITE (1 SHL I:7); { Demo Shift Left Operator }<p>
      WRITELN;<p>
      WRITE ('Demo SHR : ');<p>
      FOR I := 1 TO 8 DO WRITE (256 SHR I:7); { Demo Shift Right Operator }<p>
      WRITELN;<p>
      WRITE ('Demo SHL mit Überlauf: ');<p>
      FOR I := 1 TO 8 DO WRITE (256 SHL I:7); { Demo Shift Left Operator }<p>
      WRITELN;<p>

      WRITELN;<p>
      WRITELN('Byteberechnungen');<p>
      Byte_A := 127;<p>
      Byte_B := 2;<p>

      Word_V:=Byte_A*Byte_B; { hier läuft keiner der Operatoren über }<p>
      WRITELN(Byte_A,' * ',Byte_B,' = ',Word_V:10);<p>

      Word_V:=Byte_A*Byte_B+2;<p>
      WRITELN(Byte_A,' * ',Byte_B,' + 2 = ',Word_V:10);<p>

      Word_V:=Byte_A*Byte_B+65282; { l„uft ber ab 65535 }<p>

      WRITELN(Byte_A,' * ',Byte_B,' + 65282 = ',Word_V:10);<p>

      WRITELN;<p>
      WRITELN('Realberechnungen: RealVar := IntVar1 * IntVar2');<p>
      Real_V:=Int_A*Int_A;<p>
      WRITELN(Int_A,' * ',Int_A,' = ',Real_V:10:0);<p>

      WRITELN;<p>
      WRITELN('Programmende NUMPROBL')<p>
      END.<p&gt

      Comment


      • #4
        Hallo Dirk,
        gerade fiel mir ein, es gibt ja den DateTimePicker. Mit gehts natürlich noch viel einfacher:<p>
        procedure TForm1.DateTimePickersChange(Sender: TObject);<p>
        VAR<p>
        Tag1, Tag2,<p>
        Monat1, Monat2,<p>
        Jahr1, Jahr2 : WORD; // Aktualparameter DecodeDate sind Word<p>
        TDiff : INTEGER;<p>

        begin<p>
        DecodeDate(DateTimePicker1.Date, jahr1, monat1, tag1);<p>
        DecodeDate(DateTimePicker2.Date, jahr2, monat2, tag2);<p>

        TDiff := ABS( Tag2 - Tag1<p>
        + (Monat2 - Monat1) * 30<p>
        + (Jahr2 - Jahr1 ) * 360);<p>

        Label2.Caption := Format('%d Tage',[TDiff]);<p>
        end;<p&gt

        Comment


        • #5
          Hallo Thomas,

          der TDateTimePicker ist 'ne gute Idee!

          Was das andere Problem angeht, kann ich Dir leider nicht helfen, weil ich nur in Delphi (z.Z. 4) und VBA programmiere

          Comment


          • #6
            Hi Thomas

            Zum Problem der Integer Multiplication. Du hast es richtig erkannt, dadurch das Int_B := 2 ist und nicht mehr verändert wird nimmt der Compiler diese als Konstante. Nun, 4*2 ist langsamer als 4 shl 1 und das ist das problem: normalerweise müsste Pascal 4 sal 1 nutzten, also einen Arithmetic Shift, ABER das ist in einigen Pascal/Delphi Version jedesmal anders. Ich habe mich daran gewöhnt und stolpere jedesmal bei D4 das diesen "Bug" korregiert hat und somit noch mehr Bugs erzeugt :-)

            Gruß Hage

            Comment

            Working...
            X