[gelöst] Durch Variable dividieren

Für Fragen von Einsteigern und Programmieranfängern...
Marc
Lazarusforum e. V.
Beiträge: 208
Registriert: Fr 11. Nov 2016, 14:09
OS, Lazarus, FPC: Linux Mint 20 (WinXP VBox)
CPU-Target: 64Bit
Wohnort: Schweiz

[gelöst] Durch Variable dividieren

Beitrag von Marc »

Ich habe wieder mal ein kleines Problem.
Mache ich sowas:

Code: Alles auswählen

 
  LocTeiler := <variable aus record>
  LocResult := (LocMultiplicator*100) / LocTeiler;


kriege ich ein SIGPFE Fehler beim kompilieren.
Es ist ein Integer Wert in einem Record duch den geteilt werden soll.
Durch andere Variablen (nicht aus record) kann ich dividieren.

Das Problem habe ich nur mit der 1.8.4 Version unter win7.
Unter XP mit der Version 1.6.4 habe ich das Problem nicht.
Muss man da was konfigurieren in 1.8.4?
Zuletzt geändert von Marc am Do 9. Aug 2018, 23:53, insgesamt 1-mal geändert.
Good code comes from experience, experience comes from bad code.

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6198
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Durch Variable dividieren

Beitrag von af0815 »

Schau dir mit dem Debugger die Variable LocTeiler an, ob die nicht vielleicht 0 ist.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Warf
Beiträge: 1908
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: Win10 | Linux
CPU-Target: x86_64

Re: Durch Variable dividieren

Beitrag von Warf »

Marc hat geschrieben:kriege ich ein SIGPFE Fehler beim kompilieren.


Beim kompilieren? Also knallt fpc.exe mit der SIGPFE? Oder meinst du du bekommst den Fehler beim Ausführen/Debuggen. Für den ersten Fall, herzlichen glückwunsch du hast einen breaking bug im FPC gefunden musst ihn nur noch profilen und einen Bugreport einreichen (das ist easy für einen SIGFPE), für den zweiten Fall, PFE ist ein Arithmetischer Fehler, wahrscheinlich divide by zero. Andere tolle alternativen sind, eine der Zahlen ist NaN (Not a Number) oder du jonglierst mit infinity.

Ansonsten gibt dir beide seiten der Division einfach mal mit ShowMessage oder WriteLn aus

Marc
Lazarusforum e. V.
Beiträge: 208
Registriert: Fr 11. Nov 2016, 14:09
OS, Lazarus, FPC: Linux Mint 20 (WinXP VBox)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Durch Variable dividieren

Beitrag von Marc »

Danke für die Antworten.
Das passiert beim compilieren.
So etwas bricht ab:

Code: Alles auswählen

  LibDat[1].Data[4445].NrOfWrong[4] := 5;
  LocTeiler :=  LibDat[1].Data[4445].NrOfWrong[4];
  LocResult := 100 / LocTeiler;


So etwas nicht:

Code: Alles auswählen

  LocTeiler :=  LibDat[1].Data[4445].NrOfWrong[4];
  LibDat[1].Data[4445].NrOfWrong[4] := 5;
  LocResult := 100 / LocTeiler; 


Nätürlich könnte die Variable null annehmen. Das tut sie aber nicht.
Und eben, in der alten Version 1.6.4 gehen beide Varianten.
Good code comes from experience, experience comes from bad code.

Warf
Beiträge: 1908
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: Win10 | Linux
CPU-Target: x86_64

Re: Durch Variable dividieren

Beitrag von Warf »

Marc hat geschrieben:Danke für die Antworten.
Das passiert beim compilieren.
[...]
Nätürlich könnte die Variable null annehmen. Das tut sie aber nicht.
Und eben, in der alten Version 1.6.4 gehen beide Varianten.


Wenn es beim Kompilieren geschieht ist das ein Fehler des FPC's. 1.8.4 verwendet soweit ich weiß die aktuellste FPC version (3.0.4), da wäre es Interresant zu wissen ob der Fehler auch im trunk ist und einen Bugreport einzureichen. Dann am besten versuchen den Fehler zu isolieren (ein minimal beispiel finden) und falls das nicht möglich sein sollte (was sehr gut sein kann da breaking bugs meißt in extrem seltene situationen auftreten) und du dein Projekt nicht komplett teilen möchtest/kannst kannst du versuchen den Fehler selbst zu lokalisieren (fpc als debug build compilen, im gdb die SIGPFE finden und den backtrace sowie die lokalen variablen ausgeben lassen) und das dann als Bugreport zu senden.

Ich denke mal wenn es ein breaking bug ist wird dir hier sonst keine groß helfen können. Versuch eventuell mal andere FPC versionen (einfach auf freepascal.org runterladen und in den Lazarus einstellungen unter Compilerpfade den neuen pfad angeben). Eventuell reicht es auch schon die Optimierungsstufe zu ändern, kann aber praktisch alles sein.

Marc
Lazarusforum e. V.
Beiträge: 208
Registriert: Fr 11. Nov 2016, 14:09
OS, Lazarus, FPC: Linux Mint 20 (WinXP VBox)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Durch Variable dividieren

Beitrag von Marc »

Habe gerade versucht das in einem kleinen Demo nachzuvollziehen.
Aber so klappt es natürlich.
Muss da wohl noch etwas recherchieren.
Good code comes from experience, experience comes from bad code.

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: Durch Variable dividieren

Beitrag von wp_xyz »

Also, von einem FPC-Bug zu reden, erscheint mir bei so einfachen Operationen und so einfachen Zahlen weit hergeholt. Sowas hätte schon lange jemand gefunden.

Wie so oft, kann man mit den Angaben nichts anfangen. Du sagst, dass der folgende Code beim Kompilieren abbricht, sagst aber nicht, was sich hinter LibDat, LibDat.Data, LibDat.Data.NrOfWrong verbirgt.

Code: Alles auswählen

  LibDat[1].Data[4445].NrOfWrong[4] := 5;
  LocTeiler :=  LibDat[1].Data[4445].NrOfWrong[4];
  LocResult := 100 / LocTeiler;

Dieses Projekt habe ich mir nach deinen spärlichen Angaben zusammengeklickt:

Code: Alles auswählen

program Project1;
type
  TData = record
    NrOfWrong: array[0..4] of Integer;
  end;
  TLibData = record
    Data: array[0..4445] of TData;
  end;
 
var
  LibDat: array[0..1] of TLibData;
  LocTeiler: Integer;
  LocResult: Double;
 
begin
  LibDat[1].Data[4445].NrOfWrong[4] := 5;
  LocTeiler := LibDat[1].Data[4445].NrOfWrong[4];
  LocResult := 100 / LocTeiler;
 
  WriteLn(LocResult);
  ReadLn;
end.

Kein Problem beim Kompilieren, und zur Laufzeit auch nicht. Letztendlich wird ja nur 100 durch 5 dividiert. Wenn das der FPC nicht kann!

Wahrscheinlich liegt das Problem an den Datenstrukturen, denn das was ich mir oben aus der Kristallkugel gesaugt habe, hat wahrscheinlich nichts mit deinen Vorgaben zu tun. Poste, was hinter den Records sonst noch alles steckt. Wenn da noch ein Array[0..100000000000, 0..10000000000] of integer irgendwo eingebaut ist, dann wundert mich nicht, dass FPC aufmuckt.

Mathias
Beiträge: 6160
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Durch Variable dividieren

Beitrag von Mathias »

Kannst du mal die Deklaration von LibDat zeigen ?
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Marc
Lazarusforum e. V.
Beiträge: 208
Registriert: Fr 11. Nov 2016, 14:09
OS, Lazarus, FPC: Linux Mint 20 (WinXP VBox)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Durch Variable dividieren

Beitrag von Marc »

Ich habe das ganze programm mal mit XP und 1.6.4 compiliert.
Da geht das auch nicht.
Muss also schon an meinem Code liegen.
Good code comes from experience, experience comes from bad code.

Warf
Beiträge: 1908
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: Win10 | Linux
CPU-Target: x86_64

Re: Durch Variable dividieren

Beitrag von Warf »

wp_xyz hat geschrieben:Also, von einem FPC-Bug zu reden, erscheint mir bei so einfachen Operationen und so einfachen Zahlen weit hergeholt. Sowas hätte schon lange jemand gefunden.


Ein SIGPFE ist bei dir kein bug? Meine vorstellung von einem bug ist ein Fehler der nicht abgefangen/behandelt wird. Und da die SIGPFE meldung rausgeht scheint mir das nicht behandelt. (Der FPC ist zwar nicht so verbos, aber normalerweise doch detailierter als das)

Und das sowas schon lange gefunden würde ist auch falsch. Ich arbeite an der Uni im bereich automatisiertes Testen und es kommt öfter vor das Breaking bugs gefunden werden selbst in so gut getesteten Programmen wie den coreutils (Klee OSDI paper hat mehrere Breaking bugs in der Coreutils und Busybox gefunden). Diese fehler sind so unfassbar selten, das man sehr spezielle setups braucht um sie zu triggern. Wahrscheinlich hatte Marc einfach extrem viel pech (oder glück, immerhin ist das finden von bugs ja was gutes da sie dann gefixt werdenkönnen). Kommt vor.

Poste doch einfach mal den compiler log von deinem projekt (also die letzen paar zeilen des Nachrichtenfensters wenn du versuchst zu kompilieren). Vielleicht steht ja irgendwas relevantes drin

Marc
Lazarusforum e. V.
Beiträge: 208
Registriert: Fr 11. Nov 2016, 14:09
OS, Lazarus, FPC: Linux Mint 20 (WinXP VBox)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Durch Variable dividieren

Beitrag von Marc »

Hier ist die Datenstruktur.

Code: Alles auswählen

unit variables;
 
{$mode objfpc}{$H+}
 
interface
 
uses
  Classes, SysUtils;
 
 
 
 
TYPE VocRecord = RECORD
 
    RecordNr : Integer;
 
    LessonNr : String[5];    // Lektion oder Kapitel Number
    IdentNr : String[15];
 
    VocNewDateTime : TDateTime;
    CreateUserName : String[15]// who made this translation
 
    Category : String[15];
 
    VocChangeDateTime : Array [1..8] of TDateTime;
    VocChangeUserName : Array [1..8] of String[15]// who made this translation
 
    NrOfRight : Array [1..8] of Integer;
    NrOfWrong : Array [1..8] of Integer;
    ActPoints : Array [1..8] of Integer;
 
    SysBlock : Array [1..8] of Boolean;
    UsrBlock : Array [1..8] of Boolean;
    Pons  : Array [1..8] of Boolean;
 
    CodeInfo    : Array [1..8] of Byte;
 
 
    LevelNr       : Array [1..8] of Integer;   // 0 = unlearned 9 = Learned
    LevelDateTime : Array [1..8] of TDateTime;
 
    VocGramType : Array [1..8] of Integer;
 
    VocLang1GenusMale    : Array [1..8] of Boolean;
    VocLang1GenusFemale  : Array [1..8] of Boolean;
    VocLang1GenusNeutral : Array [1..8] of Boolean;
 
    VocLangGenus : Array [1..8] of String[5];
    VocLang      : Array [1..8] of String[30];
 
    VocLangAlt   : Array [1..8] of String[30];       // Alternative 1 translation
    VocLangHelp  : Array [1..8] of String[30];
    VocLangLaut  : Array [1..8] of String[30];
 
 
END;
 
 
TYPE LibRecord = RECORD
 
      PrgName : String[15];
      PrgVers : String[15];
      PrgDate : String[15];
 
      ActLngNr : Integer;   // 1=English 2=German 3=French 4=Malgash
      SLang : Integer;   // Abfrage zb. von Deutsch = 2
      DLang : Integer;   // Engeben Antworten zb in Franz = 3
 
      DateTimeCreated : TDateTime;
      DateTimeLastSaved : TDateTime;
 
      DateTimeLastUsed : TDateTime; // What for?
 
      FileName : String[255];
      FileExt : String[5];        // Filename extension *.dat
      PathToData : String[255];
 
      ID : String[30];       // What for?
      UserName : String[30]// who made this library
 
      Nr : Byte;       // what for ?
      ContainsData : Boolean;     // what for?
 
      NrOfVocables : integer;
      ActLibIndex : integer;
 
      ActLoopIndex : integer;
      LoopSize : Integer;
 
      MaxNrOfSpeedPoints : Integer;
      VocIndex : ARRAY [0..254] OF Integer;  // just keep the library record numbers
 
      CorrectLibInARow : Integer;
      IncreaseLoopSize : Integer;
 
      WrongLibInARow : Integer;
      DecreaseLoopSize : Integer;
 
      PointLossPerMinute : Integer;     // maybe not needed
      PointGoalPerDay : Integer;
 
      TodayInput : Integer;
      TodayRight : Integer;
      TodayWrong : Integer;
 
      TotalInputs : Integer;
      TotalRight : Integer;
      TotalWrong  : Integer;
 
      TodayLeveled : Integer;
      TotalLeveled : Integer;
      TodayLearned : Integer;
      TotalLearned : Integer;
 
      Lang1Nameq : String[30];
      Lang2Name : String[30];
 
      WordTypeShort : ARRAY [0..10] OF String[3];
      WordTypeTxt : ARRAY [0..10,0..8] OF String[30];
      WordTypeCnt : ARRAY [0..10,0..8] OF Integer;
 
 
      TodayNewVerb1 : String[15];
      TodayNewVerb2 : String[15];
 
      TodayOldVerb1 : String[15];
      TodayOldVerb2 : String[15];
 
      DailyPoints : Array[0..99] of Integer;
      DailyDate   : Array[0..99] of TDateTime;
 
      LevelRepeatArray : Array[1..12] of Integer;
      LevelReaskArray  : Array[1..12] of Integer;
 
      Data : ARRAY [0..5000] OF VocRecord;
 
      ControlNr : Byte;
END;
 
  LibArray = ARRAY [1..1] OF LibRecord;
 
 
 
var
 
 
  LibDat : LibArray;
  LibDatei : FILE OF LibArray;
 
 
 
implementation
 
procedure BeepMe;
var s:string;
begin
 //  runcommand('/usr/bin/aplay', ['/home/pi/beep-02.wav'],s);
end;
 
end.
 
Good code comes from experience, experience comes from bad code.

Marc
Lazarusforum e. V.
Beiträge: 208
Registriert: Fr 11. Nov 2016, 14:09
OS, Lazarus, FPC: Linux Mint 20 (WinXP VBox)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Durch Variable dividieren

Beitrag von Marc »

Danke für die viele Hilfe!

Soll übrigens ein Vokabeltrainer werden. :-)
Zuletzt geändert von Marc am Do 9. Aug 2018, 21:43, insgesamt 2-mal geändert.
Good code comes from experience, experience comes from bad code.

Marc
Lazarusforum e. V.
Beiträge: 208
Registriert: Fr 11. Nov 2016, 14:09
OS, Lazarus, FPC: Linux Mint 20 (WinXP VBox)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Durch Variable dividieren

Beitrag von Marc »

Das habe ich im Nachrichtenfenster:
Projekt kompilieren, OS: win32, CPU: i386, Ziel: BWord.exe: Erfolg, Hinweise: 54
lesson.pas(1142,3) Note: Local variable "MaxLinesCount" not used
lesson.pas(1143,3) Note: Local variable "MaxRowsCount" not used
lesson.pas(1150,18) Note: Local variable "NumberString" not used
lesson.pas(1156,7) Note: Local variable "IsControlLine" not used
lesson.pas(1159,5) Note: Local variable "TempInt" not used
lesson.pas(1166,6) Note: Local variable "LocLevel2Nr" not used
lesson.pas(1167,6) Note: Local variable "LocLevel2Val" not used
lesson.pas(1171,6) Note: Local variable "PartRecordNr" is assigned but never used
lesson.pas(1174,6) Note: Local variable "PartIdentNr" is assigned but never used
lesson.pas(1176,6) Note: Local variable "PartVocNewDateTime" is assigned but never used
lesson.pas(1177,6) Note: Local variable "PartCreateUserName" is assigned but never used
lesson.pas(1181,6) Note: Local variable "PartVocChangeDateTime" is assigned but never used
lesson.pas(1182,6) Note: Local variable "PartVocChangeUserName" is assigned but never used
lesson.pas(1192,6) Note: Local variable "PartCodeInfo" is assigned but never used
lesson.pas(1198,6) Note: Local variable "PartLevelDateTime" is assigned but never used
lesson.pas(1817,3) Note: Local variable "LocVocIsInLoop" is assigned but never used
lesson.pas(237,57) Hint: Parameter "UTF8Key" not used
lesson.pas(238,57) Hint: Parameter "UTF8Key" not used
lesson.pas(239,57) Hint: Parameter "UTF8Key" not used
lesson.pas(240,57) Hint: Parameter "UTF8Key" not used
lesson.pas(241,57) Hint: Parameter "UTF8Key" not used
lesson.pas(242,57) Hint: Parameter "UTF8Key" not used
lesson.pas(243,57) Hint: Parameter "UTF8Key" not used
lesson.pas(244,57) Hint: Parameter "UTF8Key" not used
lesson.pas(280,11) Hint: Parameter "UTF8Key" not used
lesson.pas(282,11) Hint: Parameter "UTF8Key" not used
lesson.pas(284,11) Hint: Parameter "UTF8Key" not used
lesson.pas(286,11) Hint: Parameter "UTF8Key" not used
lesson.pas(288,11) Hint: Parameter "UTF8Key" not used
lesson.pas(290,11) Hint: Parameter "UTF8Key" not used
lesson.pas(292,11) Hint: Parameter "UTF8Key" not used
lesson.pas(294,11) Hint: Parameter "UTF8Key" not used
lesson.pas(296,11) Hint: Parameter "UTF8Key" not used
lesson.pas(298,11) Hint: Parameter "UTF8Key" not used
lesson.pas(300,11) Hint: Parameter "UTF8Key" not used
lesson.pas(302,11) Hint: Parameter "UTF8Key" not used
lesson.pas(304,11) Hint: Parameter "UTF8Key" not used
lesson.pas(306,11) Hint: Parameter "UTF8Key" not used
lesson.pas(308,11) Hint: Parameter "UTF8Key" not used
lesson.pas(310,11) Hint: Parameter "UTF8Key" not used
lesson.pas(249,58) Hint: Parameter "UTF8Key" not used
lesson.pas(250,63) Hint: Parameter "UTF8Key" not used
lesson.pas(252,63) Hint: Parameter "UTF8Key" not used
lesson.pas(254,63) Hint: Parameter "UTF8Key" not used
lesson.pas(256,63) Hint: Parameter "UTF8Key" not used
lesson.pas(258,63) Hint: Parameter "UTF8Key" not used
lesson.pas(260,63) Hint: Parameter "UTF8Key" not used
lesson.pas(262,63) Hint: Parameter "UTF8Key" not used
lesson.pas(265,63) Hint: Parameter "UTF8Key" not used
lesson.pas(315,51) Hint: Parameter "CanClose" not used
lesson.pas(320,57) Hint: Parameter "MousePos" not used
lesson.pas(321,11) Hint: Parameter "Handled" not used
lesson.pas(361,59) Hint: Parameter "MousePos" not used
lesson.pas(361,80) Hint: Parameter "Handled" not used
Good code comes from experience, experience comes from bad code.

Mathias
Beiträge: 6160
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Durch Variable dividieren

Beitrag von Mathias »

Projekt kompilieren, OS: win32, CPU: i386, Ziel: BWord.exe: Erfolg, Hinweise: 54

Könnte es sein, das du im einten Window 32Bit und im anderen 64Bit kompilierst ?

PS: Hast du gesehen, das dein MeBeep für Linux (Raberry) ist ?
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Marc
Lazarusforum e. V.
Beiträge: 208
Registriert: Fr 11. Nov 2016, 14:09
OS, Lazarus, FPC: Linux Mint 20 (WinXP VBox)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Durch Variable dividieren

Beitrag von Marc »

Ja das ist so.
Ich habe Windows7 und XP jeweils in einer Virtual box. Das auf einem Linux Mint. Beide Windows greifen auf das selbe Datenverzeichniss zu das von Linux zur Verfügung ist.
Normal probiere ich alles in Windows 7. Wenn nötig kann ich einen Code dann auch mit XP compilieren.
Ist das nicht gut?
Das mit dem PI weiss ich. :-) Hätte es rauslöschen sollen, verwirrt nur.
Mein Code ist immer irgendwie copy & paste.
Will meinem Progrämmchen später noch ein paar Geräusche beibringen, aber das hat noch Zeit.

Sind meine Variablen totaler Schrott oder müsste das funktionieren?
Ist so einfach wie möglich. Bin auch ständig was am ändern daran.
Good code comes from experience, experience comes from bad code.

Antworten