Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien

[c#] Fouten in afronding

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

  • Ruben314199
  • Registratie: Juli 2002
  • Laatst online: 06-04 21:08
Ik trek in C# (VS2005, .net2.0) twee doubles van elkaar af. Op een of andere manier is het antwoord niet wat ik verwacht. Iemand een idee waarom? En hoe dit te ondervangen is?

Voorbeeld:
code:
1
2
3
4
5
double a, b;
            a = 9.3;
            b = 8.535;
            double c = a - b;
            System.Windows.Forms.MessageBox.Show(a.ToString() + " - " + b.ToString() + " = " + c.ToString());


geeft als output: 9.3 - 8.535 = 0.765000000000001

De gaafste watergekoelde pc ter wereld


  • BasieP
  • Registratie: Oktober 2000
  • Laatst online: 19-10 08:18
floating-point values :)
die dingen zijn nou eenmaal niet precies

zie hier

[ Voor 42% gewijzigd door BasieP op 29-08-2007 12:31 ]

This message was sent on 100% recyclable electrons.


  • whoami
  • Registratie: December 2000
  • Laatst online: 10:52
Wat BasieP zegt.
Als je echt 100% precisie wilt, moet je Decimals gebruiken.

https://fgheysels.github.io/


  • BasieP
  • Registratie: Oktober 2000
  • Laatst online: 19-10 08:18
wat ik ook vaak doe als ik geen keus heb, is afronden op het minste getal achter de komma. in jouw geval dus 1.
dus Math.Round(c, 1);

Dit is zelfs wetenschappelijk verantwoord ;)

[ Voor 20% gewijzigd door BasieP op 29-08-2007 12:38 ]

This message was sent on 100% recyclable electrons.


  • whoami
  • Registratie: December 2000
  • Laatst online: 10:52
Het 'minste' getal achter de komma is in TS z'n voorbeeld 0. :P

Maar, waarom zou je het zo willen doen ? Gewoon decimals gebruiken; ben je van het probleem af, en je hebt dan zowiezo geen kans op fouten, want dergelijke fouten kunnen wel eens heel vervelend zijn in de financiele wereld bv.

https://fgheysels.github.io/


Verwijderd

Ofwel zo een double omzetten naar een decimal met X decimalen?

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Waarom omzetten en niet van meet-af-aan een decimal gebruiken?

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 11:36

.oisyn

Moderator Devschuur®

Demotivational Speaker

BasieP schreef op woensdag 29 augustus 2007 @ 12:29:
floating-point values :)
die dingen zijn nou eenmaal niet precies

zie hier
Doubles zijn best precies. Althans, ik vind 16 significante cijfers best precies.
whoami schreef op woensdag 29 augustus 2007 @ 12:32:
Wat BasieP zegt.
Als je echt 100% precisie wilt, moet je Decimals gebruiken.
Ook Decimals zijn niet 100% precies hoor :). Het verschil tussen een Decimal en een Double is dat de eerste werkt in base-10, en de laatste in base-2. Aangezien we het decimale talstelsel gewend zijn is een Decimal wat handiger om getallen als 9.3 en 8.535 in op te slaan. Maar ook een Decimal kan een getal als 1/3 of pi niet precies opslaan. Een Decimal heeft trouwens 28 significante cijfers, en is daarmee wel preciezer dan een double.

[ Voor 5% gewijzigd door .oisyn op 29-08-2007 13:15 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Ruben314199
  • Registratie: Juli 2002
  • Laatst online: 06-04 21:08
ok jongens, bedankt.
Niet gedacht dat dit zo'n populair onderwerp was :-).

Decimals gebruiken lijkt me een beetje onzinnig aangezien het hier gaat om meters in de offshore industrie. Een lasser ziet je aankomen met een maat met 20 cijfers achter de komma :-)

Aangezien er niet iteratief gerekend wordt ga ik voor afronding op mm. Dank voor de hulp!

De gaafste watergekoelde pc ter wereld


  • BasieP
  • Registratie: Oktober 2000
  • Laatst online: 19-10 08:18
.oisyn schreef op woensdag 29 augustus 2007 @ 13:10:
[...]


Doubles zijn best precies. Althans, ik vind 16 significante cijfers best precies.
misschien is 'precies' niet het juiste woord, en is 'exact' beter.
De TS heeft twee exacte getallen (9.3 en 8.535) en trekt deze van elkaar af.
Hier zou een exact getal uit _moeten_ komen. (immers hier is wiskundig niks vreemds aan)

Doordat het opgeslagen is in een double treed er alleen allerlei rare dingen op, waardoor het resultaat niet meer exact is.

dan kan je leuk 16 significante cijfers hebben, maar als je bij 3 cijfers achter de komma al fouten maakt vind ik ze niet precies ;)
Ook Decimals zijn niet 100% precies hoor :). Het verschil tussen een Decimal en een Double is dat de eerste werkt in base-10, en de laatste in base-2. Aangezien we het decimale talstelsel gewend zijn is een Decimal wat handiger om getallen als 9.3 en 8.535 in op te slaan. Maar ook een Decimal kan een getal als 1/3 of pi niet precies opslaan. Een Decimal heeft trouwens 28 significante cijfers, en is daarmee wel preciezer dan een double.
een decimal maakt geen fouten wanneer je netjes in zijn bereik blijft. (wat een double wel doet)
Dat wordt er bedoelt met '100% precies'.

This message was sent on 100% recyclable electrons.


  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
BasieP schreef op woensdag 29 augustus 2007 @ 13:29:
[...]
een decimal maakt geen fouten wanneer je netjes in zijn bereik blijft. (wat een double wel doet)
Dat wordt er bedoelt met '100% precies'.
Wat bedoel je met fouten?

als je 1 gedeeld door 3 doet met decimals heb je ook afrondingsfouten. Het voordeel met decimals is dat de opslag overeenkomt met de representatie die je in de taal gebruikt. Het lijkt daardoor dat er minder fouten op treden.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


  • Confusion
  • Registratie: April 2001
  • Laatst online: 01-03-2024

Confusion

Fallen from grace

.oisyn schreef op woensdag 29 augustus 2007 @ 13:10:
Ook Decimals zijn niet 100% precies hoor :).
Misschien bedoelt BasieP niet Decimal (wat dat type in C# precies is weet ik niet), maar het equivalent van het type met oneindige precisie, dat in vrijwel iedere taal bestaat?

@topicstarter:
is de link van BasieP duidelijk? Anders moet je even Googlen; er zijn legio pagina's waar het op een eenvoudige manier wordt uitgelegd. In ieder geval is hetgeen je ziet normaal :).

[ Voor 23% gewijzigd door Confusion op 29-08-2007 13:37 ]

Wie trösten wir uns, die Mörder aller Mörder?


  • BasieP
  • Registratie: Oktober 2000
  • Laatst online: 19-10 08:18
rwb schreef op woensdag 29 augustus 2007 @ 13:33:
[...]

Wat bedoel je met fouten?

als je 1 gedeeld door 3 doet met decimals heb je ook afrondingsfouten. Het voordeel met decimals is dat de opslag overeenkomt met de representatie die je in de taal gebruikt. Het lijkt daardoor dat er minder fouten op treden.
1/3 is een deling met een oneindige reeks cijfers achter de komma. Deze wordt afgerond op het einde van het bereik van je variable. Dit gebeurd met je simpele 2,50 rekenmachine ook.

Echter bij het aftrekken van twee getallen doet mijn 2,50 rekenmachine echt niet 0000000001 achter de berekening zetten.
Dat bedoel ik met fouten.

Tuurlijk is het technisch te verklaren, maar dat wil nog niet zeggen dat het 'goed' is. als je een bereik hebt van 16 cijfers en na 3 decimalen een 'fout' maakt dan mag je toch wel stellen dat een double niet precies is (zoals ik dus in mijn eerste reactie deed)
Confusion schreef op woensdag 29 augustus 2007 @ 13:34:
Misschien bedoelt BasieP niet Decimal (wat dat type in C# precies is weet ik niet), maar het equivalent van het type met oneindige precisie, dat in vrijwel iedere taal bestaat?
ja een string toch ;) :+

[ Voor 14% gewijzigd door BasieP op 29-08-2007 13:39 ]

This message was sent on 100% recyclable electrons.


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

Janoz

Moderator Devschuur®

!litemod

BasieP schreef op woensdag 29 augustus 2007 @ 13:38:
[...]

1/3 is een deling met een oneindige reeks cijfers achter de komma. Deze wordt afgerond op het einde van het bereik van je variable. Dit gebeurd met je simpele 2,50 rekenmachine ook.

Echter bij het aftrekken van twee getallen doet mijn 2,50 rekenmachine echt niet 0000000001 achter de berekening zetten.
Dat bedoel ik met fouten.

Tuurlijk is het technisch te verklaren, maar dat wil nog niet zeggen dat het 'goed' is. als je een bereik hebt van 16 cijfers en na 3 decimalen een 'fout' maakt dan mag je toch wel stellen dat een double niet precies is (zoals ik dus in mijn eerste reactie deed)
Je vergist je. Je neemt het decimale stelsel aan voor de absolute waarheid en zegt vervolgens dat het binaire stelsel gebrekkig is. Dit is niet waar. Het decimale stelsel is net zo gebrekkig als het binaire stelsel.

Die afwijking van 0000000001 is misschien wel een 'fout', maar dat is net zo'n fout als het uitschrijven van 1/3 en ergens ophouden.

[ Voor 6% gewijzigd door Janoz op 29-08-2007 13:49 ]

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


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 11:36

.oisyn

Moderator Devschuur®

Demotivational Speaker

BasieP schreef op woensdag 29 augustus 2007 @ 13:29:
[...]
misschien is 'precies' niet het juiste woord, en is 'exact' beter.
De TS heeft twee exacte getallen (9.3 en 8.535) en trekt deze van elkaar af.
Hier zou een exact getal uit _moeten_ komen. (immers hier is wiskundig niks vreemds aan)
Uit 1/3 komt ook een exact getal :)
Doordat het opgeslagen is in een double treed er alleen allerlei rare dingen op, waardoor het resultaat niet meer exact is.
En dat heeft niets met precisie te maken, maar met de basis waarin het wordt opgeslagen, zoals ik al zei. Een Decimal werkt met basis 10, wat voor ons mensen handiger werkt, en waarin getallen als 9.3 exact zijn op te slaan. Een double werkt echter met basis 2, en het getal 9.3 is niet met een eindig aantal digits in basis 2 te representeren, net zoals 1/3 dat niet is in basis 10 (en basis 2 for that matter). Als je een basis 3 datatype zou hebben, dan zou je prima 1/3 op kunnen slaan. Dat wordt dan simpelweg "0.1"
een decimal maakt geen fouten wanneer je netjes in zijn bereik blijft. (wat een double wel doet)
Dat wordt er bedoelt met '100% precies'.
Een decimal heeft, afgezien van z'n grotere precisie en een andere basis, exact dezelfde problemen als een double. 1/3 is wederom een mooi voorbeeld.
Confusion schreef op woensdag 29 augustus 2007 @ 13:34:
[...]

Misschien bedoelt BasieP niet Decimal (wat dat type in C# precies is weet ik niet), maar het equivalent van het type met oneindige precisie, dat in vrijwel iedere taal bestaat?
Bedoel je niet Java's BigDecimal? Volgens mij kent .Net niet zoiets.
BasieP schreef op woensdag 29 augustus 2007 @ 13:38:
[...]

1/3 is een deling met een oneindige reeks cijfers achter de komma.
Wederom, hangt van je basis af.
Echter bij het aftrekken van twee getallen doet mijn 2,50 rekenmachine echt niet 0000000001 achter de berekening zetten.
Dat bedoel ik met fouten.
Oh, dus omdat het in dit ene geval, waarbij de invoer toevallig te representeren in het tientallige stelsel geen fouten maakt, maakt het hele rekenmachine geen fouten?
Tuurlijk is het technisch te verklaren, maar dat wil nog niet zeggen dat het 'goed' is. als je een bereik hebt van 16 cijfers en na 3 decimalen een 'fout' maakt dan mag je toch wel stellen dat een double niet precies is (zoals ik dus in mijn eerste reactie deed)
Nogmaals, het hangt af van je invoer. Ik zou een Decimal hier ook aanraden als je met dit soort waarden werkt, wat bijv. in de financiele wereld veel gebeurt. Echter zou ik daarmee het gebruik van doubles niet meteen afschrijven als "niet precies". Zodra je wat meer gaat doen dan optellen, aftrekken en vermenigvuldigen (zoals bijv. delen, trigonometrische functies, logaritmische functies, etc.) boeit het echt niet meer en kun je zelfs beter voor de double kiezen wegens de support van de hardware.

Hier het exacte getal 2-100. Veel plezier met je decimal :). Past echter prima in een double.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • whoami
  • Registratie: December 2000
  • Laatst online: 10:52
Ruben314199 schreef op woensdag 29 augustus 2007 @ 13:22:
ok jongens, bedankt.
Niet gedacht dat dit zo'n populair onderwerp was :-).

Decimals gebruiken lijkt me een beetje onzinnig aangezien het hier gaat om meters in de offshore industrie. Een lasser ziet je aankomen met een maat met 20 cijfers achter de komma :-)
Je hoeft niet alle cijfers na de komma gebruiken hé, je kan perfect een decimal met 2 cijfers na de komma gebruiken / tonen.

https://fgheysels.github.io/


  • BasieP
  • Registratie: Oktober 2000
  • Laatst online: 19-10 08:18
@ .oysin:
je hebt gelijk, maar dit is niet waar ik op doelde.
Ik weet hoe het verhaaltje werkt, en weet dat het aan de opslagmethode ligt.

Het enige dat ik 'verdedig' is mijn stelling dat een double niet zo precies is.
Dit is zoals jij aangeeft afhankelijk van welke basis je gebruikt, echter gebruiken wij in deze wereld vooral het decimale stelsel, de topic starter gebruikt het decimale stelsel, en guess what: de input in jouw programmeer omgeving gebruikt het decimale stelsel.

Excuus dat ik niet mijn stelling door een advocaat heb laten opstellen en netjes heb laten inpakken door de vele voorwaardes waaraan voldaan moet worden, maar ik hoopte dat ik er toch wel vanuit mag gaan dat we in het topic over het 10-tallig stelsel zouden praten.. (dat was tenminste de gedachte bij mijn eerste post)

This message was sent on 100% recyclable electrons.


  • whoami
  • Registratie: December 2000
  • Laatst online: 10:52
Je bedoelt exact, aangezien precies slaat op het aantal decimalen die kunnen gebruikt worden.

https://fgheysels.github.io/


  • BasieP
  • Registratie: Oktober 2000
  • Laatst online: 19-10 08:18
whoami schreef op woensdag 29 augustus 2007 @ 14:08:
Je bedoelt exact, aangezien precies slaat op het aantal decimalen die kunnen gebruikt worden.
precies!
:+

This message was sent on 100% recyclable electrons.


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 11:36

.oisyn

Moderator Devschuur®

Demotivational Speaker

BasieP schreef op woensdag 29 augustus 2007 @ 14:01:
Het enige dat ik 'verdedig' is mijn stelling dat een double niet zo precies is.
En daarbij mijn kanttekening dat jouw definitie van precies dan niet de juiste is :)
Dit is zoals jij aangeeft afhankelijk van welke basis je gebruikt, echter gebruiken wij in deze wereld vooral het decimale stelsel, de topic starter gebruikt het decimale stelsel, en guess what: de input in jouw programmeer omgeving gebruikt het decimale stelsel.
En wat ik probeer duidelijk te maken is dat jouw definitie van "precisie" in het decimale stelsel ophoudt zodra je er wat verder mee gaat rekenen, zoals eveneens in deze wereld gebruikelijk is. Natuurlijk, als je je vasthoudt aan optellen, aftrekken en vermenigvuldigen zul je zelden tegen problemen aanlopen, en veel delingen kunnen ook nog wel. Maar als je al iets verder gaat loop je met een Decimal tegen dezelfde tekortkomingen aan als met een double. Denk aan het berekenen van de afstand tussen twee punten (wellicht geen vreemde operatie voor de topicstarter in de applicatie waar hij mee bezig is). En daar houdt het "voordeel" van een decimal tov een double toch echt op
Excuus dat ik niet mijn stelling door een advocaat heb laten opstellen en netjes heb laten inpakken door de vele voorwaardes waaraan voldaan moet worden, maar ik hoopte dat ik er toch wel vanuit mag gaan dat we in het topic over het 10-tallig stelsel zouden praten.. (dat was tenminste de gedachte bij mijn eerste post)
Ach kom op zeg.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Confusion
  • Registratie: April 2001
  • Laatst online: 01-03-2024

Confusion

Fallen from grace

Ruben314199 schreef op woensdag 29 augustus 2007 @ 13:22:
Decimals gebruiken lijkt me een beetje onzinnig aangezien het hier gaat om meters in de offshore industrie.
Tenzij je zoveel manipulaties met doubles gaat doen dat de cumulatieve afrondfout groot genoeg kan worden om binnen de gewenste significantie van je eindresultaat te vallen. (8>

Wie trösten wir uns, die Mörder aller Mörder?


  • YakuzA
  • Registratie: Maart 2001
  • Niet online

YakuzA

Wat denk je nou zelluf hey :X

Confusion schreef op woensdag 29 augustus 2007 @ 15:30:
[...]

Tenzij je zoveel manipulaties met doubles gaat doen dat de cumulatieve afrondfout groot genoeg kan worden om binnen de gewenste significantie van je eindresultaat te vallen. (8>
* YakuzA fluit en wijst naar de eerste generatie's anti-scud raket afweergeschut :X

Death smiles at us all, all a man can do is smile back.
PSN


  • Confusion
  • Registratie: April 2001
  • Laatst online: 01-03-2024

Confusion

Fallen from grace

YakuzA schreef op woensdag 29 augustus 2007 @ 15:48:
[...]

* YakuzA fluit en wijst naar de eerste generatie's anti-scud raket afweergeschut :X
Hoewel het in dat geval niet eens een opeenstapeling van meerdere afrondfouten was:
http://ta.twi.tudelft.nl/users/vuik/wi211/disasters.html

Wie trösten wir uns, die Mörder aller Mörder?


  • Ruben314199
  • Registratie: Juli 2002
  • Laatst online: 06-04 21:08
zijn jullie nu nog bezig :p

De gaafste watergekoelde pc ter wereld

Pagina: 1