Toon posts:

[Delphi] Decimalen probleem

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

Verwijderd

Topicstarter
Beste mensen,

Ik heb een vaag probleem met Delphi6. De volgende code:

a := (creep[bladePoint, right, 0] - creep[bladePoint, left, 0]) / (fireTemps[right] - fireTemps[left]);
b := (-a * fireTemps[right]) + creep[bladePoint, right, 0];
creepA := (a * firingTemperature) + b;

Levert vage resultaten op, het tussenresultaat 'a' hoort zeg maar een stuk of 12 cijfers achter de komma te hebben, dat heeft ie ook, alleen hetvolgende:

0,0019045454545455

Het vreemde is dat het getal vanaf 904 niet meer klopt, en er een reeks herhalende cijfers staan. Door deze fout krijg ik in latere berekeningen een verschil van 3-5 tienden ... dat is niet leuk |:(

Delphi verzint zelf een resultaat, zo lijkt het iig ... alle waarden zijn Extended trouwens.

Hebben jullie dit ooit gezien? Wat zou ik hieraan kunnen doen? Is er misschien een andere functie voor delen die ik kan gebruiken?

Alvast bedankt,

Sem

  • Icelus
  • Registratie: Januari 2004
  • Niet online
Verwijderd schreef op 25 oktober 2004 @ 12:07:
0,0019045454545455

Het vreemde is dat het getal vanaf 904 niet meer klopt, en er een reeks herhalende cijfers staan.
Wat zou het resultaat dan moeten zijn volgens jou?

Houd er rekening mee dat rekenen met floating-point nooit "nauwkeurig" is. Een computer rekent in het 2-tallig stelsel zodat getallen uit het 10-tallig stelsel nooit perfect kunnen worden weergegeven en er afrondingsfouten ontstaan.

Zie ook:
http://en.wikipedia.org/w...blems_with_floating-point

[ Voor 10% gewijzigd door Icelus op 25-10-2004 12:14 ]

Developer Accused Of Unreadable Code Refuses To Comment


Verwijderd

Topicstarter
het resultaat moet zijn:

0.001904318

Ik moet er ook even bij vermelden dat verder bijna alle getallen hetzelfde vertonen (de herhalende reeks aan het einde), alleen met andere getallen natuurlijk, bijvoorbeeld 0.4004590909091

Ook weet ik dat dezelfde formules in Mathlab goed kunnen worden berekend, en ik heb alles al gechecked, zoals invoerwaarden, formule enzo

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 08:05

Janoz

Moderator Devschuur®

!litemod

Ik heb tijdens mijn opleiding complete practica over significantie van float waardes en berekening van fout marges gehad. Veel mensen vergeten namelijk dat tussenresultaten altijd afgerond worden en significantie vaak over het hoofd woorden gezien.

Wat is de exacte significantie van de verschillende waarden? Zeker als (a*firetemp) en b bijna gelijk zijn is het heel begrijpelijk dat er maar een paar getallen in je resultaat significant zijn.

Kortom.. Laat eens wat waarden zien die je gebruikt in je berekening ipv alleen het antwoord.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


  • Reptile209
  • Registratie: Juni 2001
  • Laatst online: 08:34

Reptile209

- gers -

Wat nog wel eens wil helpen (om tussentijdse afrondingen te voorkomen) is om niet met tussenvariabelen a en b te werken, maar je gewenste waarde met één formule uit te rekenen.
Probeer je formule voor creepA eens met de hand uit te schrijven tot één formule met zo min mogelijk termen en kijk dan eens wat er gebeurt.

Zijn al je vars trouwens extended, of zit je ook nog eens met verschillende typen te werken?

Zo scherp als een voetbal!


Verwijderd

Topicstarter
de invoerwaarden waarbij ik dit resultaat krijg zijn:

creep[bladePoint, right, 0] = 0.3757
creep[bladePoint, left, 0] = 0.3338
fireTemps[right] = 1287
fireTemps[left] = 1265
firingTemperature = 1300

Wat dit stuk code in princiepe doet is de overeenkomende waarde van creepA aan de hand van twee punten in een lineaire grafiek van creepA als functie van fireTemps berekenen. In de standaard functie y=ax+b dus eerst a uitrekenen en vervolgens een punt invullen en b uitrekenen. Dan creepA berekenen aan de hand van a en b.

Dus inderdaad, de significantie is niet meer dan 4, maar dat neemt niet weg dat het resultaat berekend met matlab, of een rekenmachine, totaal anders is.

Zonder tussenresultaten is waarschijnlijk wel mogelijk, hoewel dat erg onoverzichtelijk zal worden, maar dat zou geen probleem moeten zijn.

Ik had eerder alles in Doubles, waar ik nu ook weer naar ben teruggegaan, maar heb altijd dezelfde type getallen gebruikt.

  • Robtimus
  • Registratie: November 2002
  • Laatst online: 20-05 20:29

Robtimus

me Robtimus no like you

Dat 0,001904545454545 * 22 (de noemer) is 0.0419, en laat dat nou net de teller zijn. Dus met deze cijfers klopt dat tussenresultaat wel degelijk.

Als je een andere waarde moet krijgen dan komt dat door afronding bij het in creep etc stoppen.

More than meets the eye
There is no I in TEAM... but there is ME
system specs


  • Tomatoman
  • Registratie: November 2000
  • Laatst online: 20-05 14:02

Tomatoman

Fulltime prutser

Die herhalende getallen zijn een eigenschap van breuken die je in het tientallig stelsel weergeeft. Probeer maar eens hoe 1/7 er in decimale notatie uitziet: 0,14285714285714285714285714285714... Je ziet dat de getallen 142857 zich tot in het oneindige blijven herhalen. Dat is geen afrondingsfout, maar gewoon een eigenschap van deze breuk.

Als je een andere breuk neemt, bijvoorbeeld 4/11, zie je dat het resultaat 0,36363636... is. Alweer heeft dit niets te maken met een rekenfout of afrondingsproblemen, maar is de eindeloze herhaling van de cijfers 3 en 6 een eigenschap van deze specifieke breuk.

Conclusie: maak je geen zorgen om de zich herhalende reeksen.

Een goede grap mag vrienden kosten.


  • jvdmeer
  • Registratie: April 2000
  • Laatst online: 20-05 23:24
Ik snap er niets meer van... :?

Ik heb het even in delphi ingetypt:
Delphi:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
program Project1;

{$APPTYPE CONSOLE}

uses
  SysUtils;
var
  a,b,bpr,bpl,ftr,ftl,ft:extended;

begin
  bpr := 0.3757;
  bpl := 0.3338;
  ftr := 1287;
  ftl := 1265;
  ft  := 1300;
  a := (bpr - bpl) / (ftr - ftl);
  writeln (a)
  b := (-a * ftr) + bpr;
  writeln ((a * ft) + b);
end.


Sorry, fout gelezen... a komt inderdaad uit op wat jij omschrijft, en ik krijg het idee dat matlab fout zit met zijn antwoord en Delphi het helemaal goed berekend.

Heb jij dit ook zo in Matlab berekend? Of zijn de waarden die jij opgeeft (bij mij bpr en bpl) al afgeronde tussenresultaten?

[ Voor 39% gewijzigd door jvdmeer op 25-10-2004 21:21 . Reden: Fout gelezen ]


Verwijderd

Topicstarter
matlab gebruikt dezelfde invoerwaarden en dezelfde berekening. Ik heb zelfs nog mijn berekening aangepast om daar helemaal zeker van te zijn.

In princiepe zijn dat inderdaad tussenresultaten die afgerond zijn, maar zoals ik al zei, matlab gebruikt ook de afgeronde waarden ...

En tomatoman, ik ga me wel zorgen maken om die verschillen omdat het uiteindelijk grote verschillen maakt...

Sem

  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 08:25

Creepy

Tactical Espionage Splatterer

Leuk.. een url naar een algemene Delphi site. Het zou leuk zijn als je uitleg zou geven waarom je zou linken naar die site, en een relevante link zou ook wel lief zijn ;)

Als je met redelijk wat getallen achter de komma gaat rekenen, dan hou je in de meeste talen ergens wel een afrondingsverschil over. Dat blijft lekker doorwerken in de rest van de berekening. Er zijn wel speciale omgevingen (ik dacht dat matlab daar 1 van was, bc is er ook zo 1) die dat een heel stuk minder hebben.

[ Voor 36% gewijzigd door Creepy op 26-10-2004 08:57 ]

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


Verwijderd

Topicstarter
ik heb eens gekeken ... maar met een gewone rekenmachine krijg je er precies hetzelfde antwoord uit!! (als delphi)

Nou begin ik me af te vragen wat matlab nou anders doet ... want daar zit m dus de fout, of iig een andere methode om getallen af te ronden of delingen te verrichten ...

Iemand hier bekend met de manier waarop matlab werkt???

  • BoomSmurf
  • Registratie: Maart 2003
  • Laatst online: 13-06-2025

BoomSmurf

Am-Ende!

MatLab gebruikt zijn eigen rekenlibrary hiervoor die 'exacter' is dan de standaard floating point die je in Delphi gebruikt (maar ook langzamer).

[ Voor 21% gewijzigd door BoomSmurf op 26-10-2004 18:41 ]


Verwijderd

Verwijderd schreef op 26 oktober 2004 @ 09:06:
ik heb eens gekeken ... maar met een gewone rekenmachine krijg je er precies hetzelfde antwoord uit!! (als delphi)

Nou begin ik me af te vragen wat matlab nou anders doet ... want daar zit m dus de fout, of iig een andere methode om getallen af te ronden of delingen te verrichten ...

Iemand hier bekend met de manier waarop matlab werkt???
Er kan ook een bugje in je matlab code zitten. Vergelijk de tussenresultaten van de berekeningen eens.

Verwijderd

Topicstarter
het probleem is opgelost.

wat bleek nou het probleem te zijn? Toch verschil van invoer 8)7

Ik heb de invoer getallen (creep) van een excel sheet afgehaald die iemand anders gemaakt had, en uitgeprint had. Dat was ook degene die in Matlab werkte (bleek trouwens mathcad te zijn ... )

In excel worden waarden die in een cel staan automatisch afgerond als de cel te klein is, zonder dat dat erg opvalt. De cellen waren dus te klein, en ik gebruikte de afgeronde waarden, en hij de originele waarden ... 0,3757 was dus 0,375695 ... en dat maakte het verschil ...

sorry dat ik hier nu pas mee kom, maar wie had dit dan ook gedacht :?

thnx voor jullie hulp,

Sem
Pagina: 1