[Delphi] floating point error (nog een keer)

Pagina: 1
Acties:
  • 354 views sinds 30-01-2008
  • Reageer

  • Mottebelke
  • Registratie: Juni 2001
  • Laatst online: 18-09 15:42
Sorry voor de dubbelpost!!

Ik heb het volgende probleem in Delphi. Bij het runnen van het volgende progje krijg ik een error: "Invalid Floating Point Operation". De error wijst dan naar de volgende regel in de code: "Gemiddelde:= Optelling / (Voldoende + Onvoldoende)".
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
procedure TForm1.ButtonResultaatClick(Sender: TObject);
  var Cijfer, Optelling, Gemiddelde, R : real ;
    Voldoende, Onvoldoende, k, Fout : integer ;
begin
  Optelling:= 0 ;
  Gemiddelde:= 0 ;
  Voldoende:= 0 ;
  Onvoldoende:= 0 ;
  for k:=0 to Memo1.Lines.Count-1 do
   begin
   val(Memo1.Lines[k], R, Fout) ;
   if Fout=0 then
    begin
    Cijfer:= StrToFloat(Memo1.Lines[k]) ;
    if Cijfer > 5.5 then
    begin
    Voldoende:= Voldoende + 1 ;
    Optelling:= Optelling + Cijfer ;
    end
    else
    begin
    Onvoldoende:= Onvoldoende + 1 ;
    Optelling:= Optelling + Cijfer ;
    end;
    end;
   end;
  EditAantal.Text:= FloatToStr(Voldoende + Onvoldoende) ;
  EditVoldoende.Text:= IntToStr(Voldoende) ;
  EditOnvoldoende.Text:= IntToStr(Onvoldoende) ;
  Gemiddelde:= Optelling / (Voldoende + Onvoldoende) ;
  EditGemiddelde.Text:= FloatToStr(Gemiddelde) ;
end;
end.

Wat doe ik fout??? Wie kan mij helpen??

  • jelmervos
  • Registratie: Oktober 2000
  • Niet online

jelmervos

Simple user

Probeer es ipv / (deling) mod (of wat het nou dev). Zie de help maar es op die 2.

"The shell stopped unexpectedly and Explorer.exe was restarted."


  • Flipmo2K
  • Registratie: April 2000
  • Niet online
Op donderdag 04 oktober 2001 15:29 schreef jelmervos het volgende:
Probeer es ipv / (deling) mod (of wat het nou dev).
Ehm, dan krijg je wel maar een integer gemiddelde, terwijl me dat niet echt de bedoeling lijkt...

  • Mottebelke
  • Registratie: Juni 2001
  • Laatst online: 18-09 15:42
IDD, De uitkomst moet wel in float zijn. Het is trouwens MOD en DIV.

  • Flipmo2K
  • Registratie: April 2000
  • Niet online
Waarom doe je bij Gemiddelde niet gewoon:
code:
1
2
For K:=0 to Memo1.Lines.Count-1 do
Gemiddelde:=Gemiddelde + StrToFloat(Memo1.Lines[k]) / Memo1.Lines.Count

Deze werkt bij mij wel hoor ;).

* Flipmo2K legt effe uit dat Mottebelke en ik bij elkaar in de klas zitten en er allebei niet uitkomen.

  • Mottebelke
  • Registratie: Juni 2001
  • Laatst online: 18-09 15:42
Op donderdag 04 oktober 2001 16:31 schreef Flipmo2K het volgende:
Waarom doe je bij Gemiddelde niet gewoon:
code:
1
Gemiddelde:=Gemiddelde + StrToFloat(Memo1.Lines[k]) / Memo1.Lines.Count
Dat kan natuurlijk niet, omdat ie nu de waarde van 1 regel deelt door alle regels (je mag geen letters tellen ;)). Dus dit werkt niet echt (dacht ik).
Iemand anders nog een oplossing??

  • Skinkie
  • Registratie: Juni 2001
  • Laatst online: 09-06-2020

Skinkie

Op naar de 500

Op donderdag 04 oktober 2001 15:29 schreef jelmervos het volgende:
Probeer es ipv / (deling) mod (of wat het nou dev). Zie de help maar es op die 2.
waarschijnlijk bedoel je... div

check ff met je ... / ...
dat de eerste waarde zeker >0 is want volgens mij krijg je dat soort errors daar juist door. Kweet er alles van... ben zelf met een cijferprogramma bezig.

Steun Elkaar, Kopieer Nederlands Waar!


Verwijderd

Op donderdag 04 oktober 2001 18:03 schreef Mottebelke het volgende:
Iemand anders nog een oplossing??
Beetje grijs gebied hier...
Je code ziet er op zich goed uit (op de indents na), maar waarom 't mis gaat???

Voor je foutafhandeling gebruik je val(), en die roept _ValExt aan (een external functie). Vervolgens gebruik je StrToFloat om de waarde op te halen (die ook weer een external function, TextToFloat, aanroept).
Ik vermoed dat ergens een string in je memo staat die val() prima vindt maar waar StrToFloat moeite mee heeft (',' ipv '.', of andersom?)

Zet 's gewoon een breakpoint op die 'Gemiddelde := ...' regel, en hou bij wat de waarden voor Optelling, Voldoende en Onvoldoende zijn, dan kom je er snel genoeg achter.

edit:
O ja, een 5.5 is ook een voldoende, hoor! :)

  • Mottebelke
  • Registratie: Juni 2001
  • Laatst online: 18-09 15:42
Op donderdag 04 oktober 2001 18:13 schreef Afterlife het volgende:
Beetje grijs gebied hier...
Je code ziet er op zich goed uit (op de indents na), maar waarom 't mis gaat???

Voor je foutafhandeling gebruik je val(), en die roept _ValExt aan (een external functie). Vervolgens gebruik je StrToFloat om de waarde op te halen (die ook weer een external function, TextToFloat, aanroept).
Ik vermoed dat ergens een string in je memo staat die val() prima vindt maar waar StrToFloat moeite mee heeft (',' ipv '.', of andersom?)

Zet 's gewoon een breakpoint op die 'Gemiddelde := ...' regel, en hou bij wat de waarden voor Optelling, Voldoende en Onvoldoende zijn, dan kom je er snel genoeg achter.

edit:
O ja, een 5.5 is ook een voldoende, hoor! :)
Hum, volgens mij zeg je dus, dat er verschil zit tussen een komma en een punt (ik gebruik bij de getalleninvoer een komma, want een punt accepteerd ie niet).
Wat betreft die breaks, ik zal het even nakijken.

  • Mottebelke
  • Registratie: Juni 2001
  • Laatst online: 18-09 15:42
Ik heb dus even gekeken m.b.v. breaks en watches en zie dat bij de regel: "Gemiddelde:= Optelling / (Voldoende + Onvoldoende)" er de volgende waarden gelden:
Voldoende: 0
Onvoldoende: 0
Optelling: 0
Gemidddelde: 2.12199E-314 (zeer klein getal dus)

Zo te zien loopt er dus iets fout voor deze regel, waardoor alle waardes op nul staan.

edit:

Ik ben wel tot de ontdekking gekomen dat het wel werkt als ik integer getallen invul. Dan kloppen alle uitkomsten wel.

  • packman
  • Registratie: November 2000
  • Laatst online: 17-12-2024
Op donderdag 04 oktober 2001 20:32 schreef Mottebelke het volgende:
Ik heb dus even gekeken m.b.v. breaks en watches en zie dat bij de regel: "Gemiddelde:= Optelling / (Voldoendes + Onvoldoendes)" er de volgende waarden gelden:
Voldoende: 0
Onvoldoende: 0
Optelling: 0
Gemidddelde: 2.12199E-314 (zeer klein getal dus)

Zo te zien loopt er dus iets fout voor deze regel, waardoor alle waardes op nul staan.
ik dacht ook meteen zoiets. "(Voldoende + Onvoldoende)" zal waarschijnlijk op 0 staan (of iets heel klein da naar 0 wordt afgerond...)

EDIT:
Probeer uw target is nen double te maken (of hebt ge da nie in Delphi? <- te lang geleden )

I heard if you play the XP CD backwards, you get a satanic message. Thats nothing compared to what happens if you play it forward, then it installs Windows XP born2oc.be - Facts Of Life


Verwijderd

Optelling is 0, dus je hebt 2 mogelijkheden:
- Je memo is leeg ;)
- val(Memo1.Lines[k], R, Fout) levert steeds een Fout <> 0 op.

Oorzaak: die komma als decimal separator. Val() vindt dat niet fijn.

En ja, deling door 0 is een 'illegal floating point operation'...

Verwijderd

Handig functietje:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function StrTran(AString: string; const ASearch, AReplace: string): string;
var
  iPos: integer;
begin
  Result := '';
  iPos := 1;
  while iPos > 0 do begin
    iPos := Pos(ASearch, AString);
    if iPos > 0 then begin
    Result := Result + Copy(AString, 1, iPos-1) + AReplace;
    AString := Copy(AString, iPos + Length(ASearch), Length(AString));
    end;
  end;
  Result := Result + AString;
end;

StrTran(<string>, ',', '.') vervangt bv. alle komma's door punten. :)

  • Mottebelke
  • Registratie: Juni 2001
  • Laatst online: 18-09 15:42
Op donderdag 04 oktober 2001 20:54 schreef Afterlife het volgende:
Handig functietje:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function StrTran(AString: string; const ASearch, AReplace: string): string;
var
  iPos: integer;
begin
  Result := '';
  iPos := 1;
  while iPos > 0 do begin
    iPos := Pos(ASearch, AString);
    if iPos > 0 then begin
    Result := Result + Copy(AString, 1, iPos-1) + AReplace;
    AString := Copy(AString, iPos + Length(ASearch), Length(AString));
    end;
  end;
  Result := Result + AString;
end;

StrTran(<string>, ',', '.') vervangt bv. alle komma's door punten. :)
Ok, maar kan ik dit niet iets makkelijker regelen (vervangen van komma's door punten), want de code die jij geeft hebben we nog niet gehad, dus dat zullen we ook nog niet nodig moeten hebben.

Verwijderd

Op donderdag 04 oktober 2001 21:05 schreef Mottebelke het volgende:
Ok, maar kan ik dit niet iets makkelijker regelen (vervangen van komma's door punten), want de code die jij geeft hebben we nog niet gehad, dus dat zullen we ook nog niet nodig moeten hebben.
Sorry, 'k wist niet dat 't om een oefenopdracht ging...

Zonder die StrTran is 't ook wel mogelijk, en da's zelfs nog te beter. Maak gewoon gebruik van de DecimalSeparator van Windows (en in iedere Delphi applicatie kun je die ook gewoon onder die naam aanspreken).
Vergeet die val() check (die was al wat dubbel, je deed niks met R), maar gebruik direct StrToFloat. Ik ga 't niet voor je schrijven, maar iets als...
code:
1
2
3
4
5
6
7
8
// in je for lus...
  try
    Cijfer := StrToFloat(<regel uit de memo>)
    // Optelling, Voldoende, Onvoldoende, etc. afhandelen
  except
    on E: EConversionError do
    // ehmm... niks. :) dit was geen geldig getal.
  end;

Maar ik ben bang dat je die code ook nog niet hebt gehad?

  • Bergen
  • Registratie: Maart 2001
  • Laatst online: 14:26

Bergen

Spellingscontroleur

Daar gebruik ik altijd ff de voldende zelfgebakken fuctie voor, werkt altijd perfect:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function TForm1.Komma (Invoer: string): string;
var
    GoeieKomma, FouteKomma: char;
    i: word;
begin
    if not (Invoer = '') then
      begin
        GoeieKomma := FloatToStr (1/2) [2]; // pak '.' of ','
        if GoeieKomma = '.' then
            FouteKomma := ','
        else
            FouteKomma := '.';
        for i := 1 to length (Invoer) do
            if Invoer [i] = FouteKomma then
              Invoer [i] := GoeieKomma;
      end;
    result := Invoer;
end;

Tssk man ik ben gewoon half bezopen nu ik dit zit te typen, kkom net uit de kroeg... bwargh :Z

  • Mottebelke
  • Registratie: Juni 2001
  • Laatst online: 18-09 15:42
Jaja, ik heb het opgelost *D
Ik heb het validation-statement helemaal over boord gegooid en heb nu deze code gemaakt die wel werkt:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
procedure TForm1.ButtonResultaatClick(Sender: TObject);
  var k, l, Aantal, Voldoende, Onvoldoende : integer ;
    Regel, Cijfer : string ;
    Getal, Optelling, Gemiddelde : real ;
begin
  Getal:= 0 ;
  Aantal:= 0 ;
  Voldoende:= 0 ;
  Onvoldoende:= 0 ;
  Optelling:= 0 ;
  Gemiddelde:= 0 ;
  for k:=0 to Memo1.Lines.Count-1 do
   begin
   Cijfer:= '' ;
   Regel:= Memo1.Lines[k] ;
   for l:=1 to Length(Regel) do
    if Regel[l] in ['0'..'9',','] then Cijfer:= Cijfer + Regel[l] ;
   if Cijfer <> '' then
    begin
    Getal:= StrToFloat(Cijfer) ;
    Optelling:= Optelling + Getal ;
    Aantal:= Aantal + 1 ;
    if Getal >= 5.5 then
    Voldoende:= Voldoende + 1 
    else
    Onvoldoende:= Onvoldoende + 1 ;
    end;
   end;
  Gemiddelde:= Optelling / Aantal ;
  EditGemiddelde.Text:= FloatToStr(Gemiddelde) ;
  EditVoldoende.Text:= IntToStr(Voldoende) ;
  EditOnvoldoende.Text:= IntToStr(Onvoldoende) ;
  EditAantal.Text:= IntToStr(Aantal) ;
end;

Toch allemaal bedankt voor jullie hulp!!! :)

  • Flipmo2K
  • Registratie: April 2000
  • Niet online
Op vrijdag 05 oktober 2001 16:11 schreef Mottebelke het volgende:
Toch allemaal bedankt voor jullie hulp!!! :)
Graag gedaan >:)!
Pagina: 1