[Java] kan java wel rekenen?

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

  • martennis
  • Registratie: Juli 2005
  • Laatst online: 27-11 19:57
Ik stuite net op het volgende reken'probleem'... (voor java dan)

ik probeerde eerst de volgende formule:
Java:
1
int bla = 100 - (100 * (x / 5));


hierop nam ik dus aan dat voor een waarde van x=1 , bla 80 zou zijn... (mee eens? mijn rekenmachine wel iig...)
echter reageerde mijn programma niet op dezelfde manier als mij... hij gaf namelijk altijd een waarde terug van 100 :?

toen ik de formule veranderde naar:
Java:
1
2
// Merk het verschil met de haakjes met de vorige formule...
int bla = 100 - ((100 * x) / 5);


deed het programma het op eens wel :? er kwam dus een goede uitkomst uit...

maar als ik dit na reken in mijn rekenmachine.. dan zouden beide formules hetzelfde moeten geven?

waarom zou de eerste formule dit niet doen?
iemand een idee?

  • DJ Buzzz
  • Registratie: December 2000
  • Laatst online: 11-12 22:38
Is x een integer? Zo ja, dan is het niet zo gek. x / 5 is dan een integer deling, waar dus 0 uit komt...

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 20-11 11:59

NMe

Quia Ego Sic Dico.

djbuzzz schreef op woensdag 17 augustus 2005 @ 20:17:
Is x een integer? Zo ja, dan is het niet zo gek. x / 5 is dan een integer deling, waar dus 0 uit komt...
In dat geval is (100 * x) / 5 ook een integerdeling. ;)

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


  • martennis
  • Registratie: Juli 2005
  • Laatst online: 27-11 19:57
ja ik wou al zeggen...

als ik 1 door 5 deel (integer of double of float) komt er nog steeds 0.2 uit... en wordt bla dus 80?

  • DJ Buzzz
  • Registratie: December 2000
  • Laatst online: 11-12 22:38
Maar dan is het geen probleem aangezien je 100 * x eerst doet en je daarbij geen floating points nodig hebt :)

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 20-11 11:59

NMe

Quia Ego Sic Dico.

* NMe is weer eens niet wakker vandaag. :+

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


  • martennis
  • Registratie: Juli 2005
  • Laatst online: 27-11 19:57
ok.. dus als ik je goed begrijp bedoel je ongeveer het volgende:

1/5 = 0.2 (floating point dus?)

en daar zou dan een 0 uit komen? als integer dan...

[ Voor 7% gewijzigd door martennis op 17-08-2005 20:22 ]


  • Rac-On
  • Registratie: November 2003
  • Niet online
ander probeerd te topicstarter het even uit door niet x=1 te doen, maar x=1,0. of ff typecasten, da ken ook...

doet niet aan icons, usertitels of signatures


  • Gerco
  • Registratie: Mei 2000
  • Laatst online: 05:24

Gerco

Professional Newbie

Idd, x / 5 in een integer deling is gewoon 0 en 0 * 100 is nog steeds 0, trek je dat van 100 af krijg je (jawel) 100 :)

Als je daarentegen x * 100 doet, krijg je 100. Deel je dat door 5 wordt het 20 en trek je dat van 100 af krijg je netjes 80.

Probeer het anders eens met de constanten 100.0 en 5.0, je zult zien dat het dan een stuk beter gaat. 100.0 is namelijk een float en 100 een int.

- "Als ik zou willen dat je het begreep, legde ik het wel beter uit!" | All number systems are base 10!


  • martennis
  • Registratie: Juli 2005
  • Laatst online: 27-11 19:57
of casten naar float :)

  • martennis
  • Registratie: Juli 2005
  • Laatst online: 27-11 19:57
ok thnx iedereen :D

ik wist niet dat dat zo werkte :x

thnx! :D
me = happy...

heb er namelijk een halve dag over gezaagt :X

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Meest gemaakte beginners fout ;) Dus schaam je niet, hehe :P

  • DJ Buzzz
  • Registratie: December 2000
  • Laatst online: 11-12 22:38
Yeps, want 0.2 kun je niet opslaan in een integer datatype (alleen gehele getallen). In jouw geval zijn x en 5 beide integers, waarbij je dus een integer deling hebt. Een integer deling heeft altijd als antwoord het aantal maal dat het getal en geheel in past (vergelijk met module, dat altijd de rest opleverd). Wil je dat er een floating point deling wordt uitgevoerd, dan moet je er voor zorgen dat 1 van beide een float of double is. Je kunt dus b.v. x / 5.0 of (double) x / 5 gebruiken.

edit:

Het ging veels te hard ;)

[ Voor 5% gewijzigd door DJ Buzzz op 17-08-2005 20:25 ]


  • jotheman
  • Registratie: September 2000
  • Laatst online: 08-12 21:09

jotheman

Was like that when I got here!

Wat de mensen al zeggen. Als je integer aangeeft pakt ie alleen hele getallen... Maar dat had je waarschijnlijk al door. Probeer float en 't werkt.

I see dead pixels...


  • martennis
  • Registratie: Juli 2005
  • Laatst online: 27-11 19:57
Zoijar schreef op woensdag 17 augustus 2005 @ 20:24:
Meest gemaakte beginners fout ;) Dus schaam je niet, hehe :P
ik hoop niet dat je hiermee suggereert dat ik een beginner ben? ;)

// edit

ok thnx...
slot maar ;)

[ Voor 65% gewijzigd door martennis op 17-08-2005 20:27 ]


  • jotheman
  • Registratie: September 2000
  • Laatst online: 08-12 21:09

jotheman

Was like that when I got here!

martennis schreef op woensdag 17 augustus 2005 @ 20:25:
[...]

ik hoop niet dat je hiermee suggereert dat ik een beginner ben? ;)

// edit

ok thnx...
slot maar ;)
Ik hoop 't wel tbh, want anders ben je 'n ervaren programmeur die een behoorlijk domme fout maakt moet ik eerlijk zegge... B)

I see dead pixels...


Verwijderd

martennis schreef op woensdag 17 augustus 2005 @ 20:22:
ok.. dus als ik je goed begrijp bedoel je ongeveer het volgende:

1/5 = 0.2 (floating point dus?)

en daar zou dan een 0 uit komen? als integer dan...
Je kunt het ook zo zien. De integeroperatie 1/5 heeft als resultaat 0 met rest 1 (volgens mij werkten de staartdelingen op de lagere school ook zo, maar dat is al weer zo lang geleden. ;)). De rest valt weg en het resultaat is 0.

Vrijwel alle programmeertalen hebben behalve de / operator ook een % (modulo) operator waarmee je juist de rest van de deling terugkrijgt.

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

martennis schreef op woensdag 17 augustus 2005 @ 20:25:
ik hoop niet dat je hiermee suggereert dat ik een beginner ben? ;)
Haha, tsja wat jotheman al zei ;) nofi... :)

  • martennis
  • Registratie: Juli 2005
  • Laatst online: 27-11 19:57
achja...
kwil ook niet zeggen dat ik 1 van de besten ben ofzo hoor ;)
maarja.. als je die fout nog nooit eerder gemaakt heb, en er ook nog nooit van gehoord heb :)
kun je er niet veel aan doen :)

Verwijderd

martennis schreef op woensdag 17 augustus 2005 @ 20:59:
achja...
kwil ook niet zeggen dat ik 1 van de besten ben ofzo hoor ;)
maarja.. als je die fout nog nooit eerder gemaakt heb, en er ook nog nooit van gehoord heb :)
kun je er niet veel aan doen :)
Tsja, de stelling is dat als je een 'ervaren' programmeur bent (dwz iemand die tenminste een maand of 3 a 4 geprogrammeerd heeft) dat je dit dan gewoon weet. De meeste mensen leren over dit probleem in de eerste of tweede week dat ze met programmeren bezig zijn, enkele hardleerse types mischien na een maand of 2 (hoewel dat eigenlijk al niet voorkomt), en na een maand of 4 is de kans dat je dit nog niet weet eigenlijk tot 0 gereduceerd.

* Henk heeft 3 jaar lang C++ les gegeven aan 1ste jaars studenten informatica

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 02:57

.oisyn

Moderator Devschuur®

Demotivational Speaker

henk_DE_man: beetje kort door de bocht, het hangt natuurlijk sterk van de taal af. In VB kun je bijvoorbeeld prima 1 / 5 noteren waar keurig 0.2 uitkomt :)

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.


  • Bosmonster
  • Registratie: Juni 2001
  • Laatst online: 19-11 09:49

Bosmonster

*zucht*

Voor zover ik weet gaat iedere weakly typed taal zo met integer delingen op (VB/PHP om maar wat dingen te noemen) en kan dus zelfs de meest ervaren programmeur in die talen die fout maken in een andere taal.

[ Voor 4% gewijzigd door Bosmonster op 17-08-2005 23:05 ]


  • martennis
  • Registratie: Juli 2005
  • Laatst online: 27-11 19:57
Verwijderd schreef op woensdag 17 augustus 2005 @ 21:58:
[...]


Tsja, de stelling is dat als je een 'ervaren' programmeur bent (dwz iemand die tenminste een maand of 3 a 4 geprogrammeerd heeft) dat je dit dan gewoon weet. De meeste mensen leren over dit probleem in de eerste of tweede week dat ze met programmeren bezig zijn, enkele hardleerse types mischien na een maand of 2 (hoewel dat eigenlijk al niet voorkomt), en na een maand of 4 is de kans dat je dit nog niet weet eigenlijk tot 0 gereduceerd.

* Henk heeft 3 jaar lang C++ les gegeven aan 1ste jaars studenten informatica
Er is niet 1 leraar geweest bij mij op mijn school die mij dit verteld heeft :/
maarja... van je fouten moet je maar leren toch? :)

  • prototype
  • Registratie: Juni 2001
  • Niet online

prototype

Cheer Bear

martennis schreef op donderdag 18 augustus 2005 @ 11:33:
[...]


Er is niet 1 leraar geweest bij mij op mijn school die mij dit verteld heeft :/
maarja... van je fouten moet je maar leren toch? :)
Mjah, voor de volledigheid iig.
Het casten van x naar float / double binnen die expressie zorgt voor numeric promotion; alle integer values binnen de expressie worden gepromoveerd naar de grootste 'nauwkeurigheid' (respectievelijk float danwel double precision waarden), tenzij ze expliciet anders gecast zijn. Hierdoor wordt een integer deling oppeens impliciet een float of double deling.

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 02:57

.oisyn

Moderator Devschuur®

Demotivational Speaker

Overigens een sidenote, ik blijf het raar vinden dat een int naar float of een long naar double een "promotion" is, aangezien zowel de float als de double niet genoeg precisie hebben om een hele int danwel long op te slaan.

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.


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 10-12 14:13
Google term: What every computer scientist should know about floating point

[ Voor 45% gewijzigd door MSalters op 18-08-2005 23:29 ]

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


Verwijderd

.oisyn schreef op woensdag 17 augustus 2005 @ 22:58:
henk_DE_man: beetje kort door de bocht, het hangt natuurlijk sterk van de taal af. In VB kun je bijvoorbeeld prima 1 / 5 noteren waar keurig 0.2 uitkomt :)
Ja, je hebt natuurlijk volkomen gelijk daarmee :) In plaats van programmeur had ik Java programmeur moeten schrijven. Omdat dit topic al over Java ging had ik dat weggelaten, maar ik zie nu dat dat toch wat verwarring veroorzaakt.

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Verwijderd schreef op woensdag 17 augustus 2005 @ 21:58:
Tsja, de stelling is dat als je een 'ervaren' programmeur bent (dwz iemand die tenminste een maand of 3 a 4 geprogrammeerd heeft) dat je dit dan gewoon weet. De meeste mensen leren over dit probleem in de eerste of tweede week dat ze met programmeren bezig zijn, enkele hardleerse types mischien na een maand of 2 (hoewel dat eigenlijk al niet voorkomt), en na een maand of 4 is de kans dat je dit nog niet weet eigenlijk tot 0 gereduceerd.
Met alle respect, maar als je "een maand of 4" 'ervaring' hebt ben je in mijn boek no where near 'ervaren programmeur'. Een jaar of 3 a 4 maybe, en dan nog durf ik twijfels te trekken bij een aantal lieden. En dat de meesten dit na een maand of 4 wel weten is in mijn ogen ook larie. Sommigen wel, uiteraard, maar anderen komen er na 15 jaar pas achter (en ja, ik ken een "oude rot in het vak" welke nog steeds moeite heeft met dit soort dingen (en ja, in mijn ogen is 'ie de handle "programmeur" dan ook niet waardig ;) )). Zo heeft deze meneer ook nog steeds moeite met het concept dat 3 + -4 = -1 en nog steeds moeite met statements waarin and/or constructies voorkomen.

[ Voor 35% gewijzigd door RobIII op 19-08-2005 00:30 ]

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


Verwijderd

RobIII schreef op vrijdag 19 augustus 2005 @ 00:28:
[...]

Met alle respect, maar als je "een maand of 4" 'ervaring' hebt ben je in mijn boek no where near 'ervaren programmeur'.
Ik snap precies wat je bedoeld, zelf programmeer ik al een jaar of 20, ben Drs. Informatica en nog steeds heb ik het gevoel dat ik nog zo ongelooflijk veel niet weet.

Waar ik echter op doelde is "ervaren genoeg om het principe van een integer deling te kennen". De clou was dat de TS dus hoogst waarschijnlijk nog minder (Java/C#/C++/etc) ervaring had als die 4 maanden.

[ Voor 5% gewijzigd door Verwijderd op 22-08-2005 17:45 ]


Verwijderd

Een beetje goochelen met de getallen levert ook dit op:

100 * (x / 5) = (100 / 5) * x = 20 * x

Dat scheelt ook meteen al een hele hoop afrondingen. Heeft als bijkomend voordeel dat de functie iets makkelijker wordt en dus ook sneller uitgerekend zal worden

[ Voor 27% gewijzigd door Verwijderd op 23-08-2005 14:22 . Reden: Toevoeging ]


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 02:57

.oisyn

Moderator Devschuur®

Demotivational Speaker

En als je niet met constante werkt is het verstandig éérst alle vermenigvuldingingen te doen, en daarna pas de delingen (vooropgesteld dat het dan nog wel in een int of long blijft passen, anders zul je uit moeten wijken naar een float of double - liefst een double, aangezien als het niet meer in een int past je meer precisie nodig hebt dan in een float kan).

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.


  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 12-12 07:42

Janoz

Moderator Devschuur®

!litemod

Als het toch over 'vreemde computer reken feitsjes hebben' dan kan het feit dat je floating point getallen niet met == mag vergelijken natuurlijk niet achter blijven.

Gegeven
code:
1
2
 float waarde1;
float waarde2;

dan nooit
code:
1
waarde1 == waarde2
, maar
code:
1
fabs(waarde1-waarde2)< epsilon



@.oisyn : epsilon is in deze niet een variabele, maar het teken dat over het algemeen in dit soort wiskunde wordt gebruikt om een minimale significante afwijking te definieren ;).

[ Voor 23% gewijzigd door Janoz op 23-08-2005 15:36 ]

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


  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Janoz schreef op dinsdag 23 augustus 2005 @ 14:51:
Als het toch over 'vreemde computer reken feitsjes hebben' dan kan het feit dat je floating point getallen niet met == mag vergelijken natuurlijk niet achter blijven.

Gegeven
code:
1
2
 float waarde1;
float waarde2;

dan nooit
code:
1
waarde1 == waarde2
, maar
code:
1
fabs(waarde1-waarde2)< epsilon
Dit zijn dus dingen die inderdaad gewoon op school erin gestampd zouden moeten worden, maar 't zijn er maar enkelen die begrijpen waarom dit zo is als ze van school komen. Dit zijn "trucjes" die doorgaans alleen bij de "ervaren" ** lieden bekend zijn.

** "ervaren" is misschien nog een groot woord, maar dit zijn in elk geval geen dingen die beginners doorgaans weten.

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: 02:57

.oisyn

Moderator Devschuur®

Demotivational Speaker

Janoz schreef op dinsdag 23 augustus 2005 @ 14:51:
maar
code:
1
fabs(waarde1-waarde2)< epsilon
Nee, een constante epsilon is net zo onhandig als de == operator, aangezien bij te grote waarden er een groter verschil dan epsilon tussen kan zitten, en bij waarden te dicht bij nul is de epsilon te groot. Als je twee waarden wilt vergelijken moet je je epsilon baseren op de exponenten van de twee getallen.

Dit geeft wel aardige resultaten:
code:
1
fabs(waarde1-waarde2) < epsilon*(waarde1+waarde2)

[ Voor 11% gewijzigd door .oisyn op 23-08-2005 15:10 ]

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.


  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Kan je niet std::numeric_limits<float>::epsilon() gebruiken? Dat vroeg ik me eigenlijk al een tijdje af, of dat nut heeft, of dat het te klein is.

Verwijderd

Aangezien niemand de vraag stelt, en Janoz er wel heel duidelijk naar zit te vissen:

"waarom mag je twee floats niet met elkaar vergelijken middels de == operator?" ;)

  • djluc
  • Registratie: Oktober 2002
  • Laatst online: 07-12 12:51
* djluc is absoluut geen java programmeur maar:
Waarom is het zo logisch dat het voorbeeld uit de TS 0 geeft? Is het niet veel logischer dat dit gewoon een foutmelding geeft? Het is net zoiets als proberen een lange plank in een kortere vierkante doos proberen te stoppen. Het kan gewoon niet. Om er dan 0 aan te geven, dat lijkt een beetje op MySQL wat zo gehaat wordt omdat dit op dezelfde manier met data omgaat. Of heeft het specifieke voordelen?

  • Sendy
  • Registratie: September 2001
  • Niet online
Het is gewoon een gevalletje doen wat er gevraagd wordt. Het is mogelijk om 1 / 5 te defineren (als integer en als float operatie). Dus als jij 1 / 5 in integer vraagt, dan krijg je je lange plank in een vierkant doosje.

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

djluc schreef op dinsdag 23 augustus 2005 @ 15:12:
* djluc is absoluut geen java programmeur maar:
Waarom is het zo logisch dat het voorbeeld uit de TS 0 geeft? Is het niet veel logischer dat dit gewoon een foutmelding geeft? Het is net zoiets als proberen een lange plank in een kortere vierkante doos proberen te stoppen. Het kan gewoon niet. Om er dan 0 aan te geven, dat lijkt een beetje op MySQL wat zo gehaat wordt omdat dit op dezelfde manier met data omgaat. Of heeft het specifieke voordelen?
Omdat voor integers 4/5 gewoon 0 is. Zo heb je het toch ook op school geleerd vroeger? 10/3 = 3 rest 1. Dus 4/5 is 0 rest 4. Als je de rest wilt weten moet je 4%5 gebruiken.

  • MisterData
  • Registratie: September 2001
  • Laatst online: 10-12 14:49
Verwijderd schreef op dinsdag 23 augustus 2005 @ 15:10:
Aangezien niemand de vraag stelt, en Janoz er wel heel duidelijk naar zit te vissen:

"waarom mag je twee floats niet met elkaar vergelijken middels de == operator?" ;)
Omdat bij het opslaan van een float (bijvoorbeeld 0.5) hij mag worden afgerond naar bijvoorbeeld 0.499999 (of dat dat bij berkeeningen gebeurt) en dat 0.499999 != 0.5 :)

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 02:57

.oisyn

Moderator Devschuur®

Demotivational Speaker

Zoijar schreef op dinsdag 23 augustus 2005 @ 15:07:
Kan je niet std::numeric_limits::epsilon() gebruiken? Dat vroeg ik me eigenlijk al een tijdje af, of dat nut heeft, of dat het te klein is.
Mja, hij is gedefinieerd als x - 1, met x de kleinst mogelijke waarde groter dan 1. Voor een reguliere float komt dat dus neer op 2-23 (= 0.0000001192), oftewel mag er een afwijking van 1 bit in de mantissa zitten. Maar zo'n afwijking kun je hebben bij 1 operatie, dus ik ben van mening dat dat idd te klein is.

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.


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 02:57

.oisyn

Moderator Devschuur®

Demotivational Speaker

MisterData schreef op dinsdag 23 augustus 2005 @ 15:19:
[...]


Omdat bij het opslaan van een float (bijvoorbeeld 0.5) hij mag worden afgerond naar bijvoorbeeld 0.499999 (of dat dat bij berkeeningen gebeurt) en dat 0.499999 != 0.5 :)
Nou je gebruik je wel weer precies een slecht voorbeeld, aangezien 0.5 een macht van 2 is en dus prima is op te slaan in binaire notatie ;). Maar voor getallen als 0.4 gaat dat idd op.

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.


  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

floats zijn ook niet associatief toch? Maw. het kan voorkomen dat a*b != b*a? Vandaar dat je compiler opties hebt voor "strict floating point", dan worden floating point operaties niet van volgorde verwisseld om consistentie tussen units te behouden.

Ik wist dat epsilon() 1 bit was, in principe kan je het wel gebruiken om veilig te delen, maar het leek me ook al te klein. Wat is dan wel een goede waarde? Ik zie vaak 1E-6 voor floats. Of misschien round_error()?

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 12-12 07:42

Janoz

Moderator Devschuur®

!litemod

Verwijderd schreef op dinsdag 23 augustus 2005 @ 15:10:
Aangezien niemand de vraag stelt, en Janoz er wel heel duidelijk naar zit te vissen:

"waarom mag je twee floats niet met elkaar vergelijken middels de == operator?" ;)
Dat heeft te maken met hoe een float opgelsagen wordt. Van het totaal aantal bits is een gedeelte gereserveerd voor de mantisse1 en een gedeelte voor de exponent. Bij binaire opslag is de radix altijd 2. De waarde van de float is dan gelijk aan mantisse * 2 ^ exponent.

Aangezien er voor de mantisse maar een eindig aantal bits beschikbaar zijn krijg je hier afrond fouten. De waarde 0.2 is bijvoorbeeld al een benadering omdat deze in het binaire talstelse niet exact weergegeven kan worden (vergelijkbaar met 1/3 in het decimale stelsel)

Bij operaties tussen floats zouden dus afrondfouten op kunnen treden!! (dat is eigenlijk de conclusie uit heel bovenstaand stuk ;) )

Waarom je nu niet == mag gebruiken zal ik even laten zien met een decimaal voorbeeldje (radix 10)

Stel we heben 4 decimale posities beschikbaar voor de mantise en we hebben de berekening 1 / 3 * 3.

waarde is 0001 met exponent 0
na bewerking /3
waarde is 3333 met exponent -4
na bewerking *3
waarde is 9999 met exponent -4

Doe je nu een vergelijking dan zie je dat 1 / 3 * 3 dus niet gelijk is aan 1.


1eigenlijk niet helemaal aangezien van de mantisse alle behalve de msb opgeslagen wordt aangezien de msb altijd 1 is.

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


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 18:39
Bosmonster schreef op woensdag 17 augustus 2005 @ 23:04:
Voor zover ik weet gaat iedere weakly typed taal zo met integer delingen op (VB/PHP om maar wat dingen te noemen) en kan dus zelfs de meest ervaren programmeur in die talen die fout maken in een andere taal.
Ruby en Python doen het niet. Perl, PHP, Lua en Javascript wel. Het is dus maar net welke weakly typed taal je gebruikt.

Als C-programmeur vind ik het fijn dat integers niet 'automatisch' omgezet worden naar floats bij deling, want ik ben gewend om zelf op te letten wanneer dat nodig is. Zoals .oisyn al zei zorgt het alleen maar voor verlies in nauwkeurigheid.

Verwijderd

Soultaker schreef op dinsdag 23 augustus 2005 @ 15:50:
Als C-programmeur vind ik het fijn dat integers niet 'automatisch' omgezet worden naar floats bij deling, want ik ben gewend om zelf op te letten wanneer dat nodig is. Zoals .oisyn al zei zorgt het alleen maar voor verlies in nauwkeurigheid.
Ter aanvulling: ik vind het vervelend dat je in weakedtyped talen een attribuut "aantalKerenSex" op bijvoorbeeld "5,3" kunt zetten :)

[ Voor 5% gewijzigd door Verwijderd op 23-08-2005 15:59 ]


  • tekno
  • Registratie: September 2001
  • Laatst online: 29-11 12:29
Het gaat hier tot nu toe vooral over delen en vermenigvuldigen.
Bij deze operaties blijft de relatieve fout nog enigzins binnen de perken.
Neem c = a * b , waarbij a een relatieve fout ea heeft en b een relatieve fout eb.
Dan is de relatieve fout van het resultaat (ec) nagenoeg ea + eb
Nemen we nu c = a / b, dan ec = ea - eb.

Nemen we nu echter de - operatie,
dan krijgen we c = a - b geeft ec = a/c * ea - b/c eb
Stel dat c dus ten opzichte van a en b klein is, dan onstaat er een grote relatieve fout in c.
Wat eigenlijk veel ernstiger is.

Hoe ga je dan iets in de trend van (a/b)-(c*d) == constante oplossen in een programmertaal.
Waarin a,b,c en d allen variabelen zijn, de 4 invoerparameters, waar dan 1 uitvoerparameter uitkomt, namelijke een boolean waarde.
Met oplossen bedoel ik dus constateren of dit inderdaad binnen de afrondingsfouten gelijk is aan de constante, of de bewering dus waar is. Analoog aan 1-0.6 == 0.4 -> true/false

Daar ben ik dan meer in geinteresseerd.
Ga je de losse delen los uitrekenen,
dus
e = a/b
f = c*d
g = e-f
| g - constante | < epsilone waarde

Ga je nu voor epsilon waarde keizen:
epsilon*(|g| + |constante|)
of epsilon*(waarde waarbij alle voorgaande fouten worden meegerekend)

Of los je dit op een andere manier op?

[ Voor 17% gewijzigd door tekno op 23-08-2005 17:19 . Reden: Getracht probleem duidelijker te omschrijven ]


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 18:39
Waar wil je precies naar oplossen? Een vergelijking met vier variabelen is natuurlijk niet oplosbaar; het lijkt me dat je oplossen naar een specifieke variabele gewoon rechtlijnig doet: a = b*(constante + c*d). Fouten neem je dan maar voor lief.

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 02:57

.oisyn

Moderator Devschuur®

Demotivational Speaker

Tenzij je een natuurkundige of wiskundige applicatie ontwikkelt waarin numeric stability een pre is, gebruik je meestal gewoon een vaste epsilon afhankelijk van de door jouw gekozen foutmarge. Als je met floats werkt dan is dat doorgaans 1e-5 of 1e-6, dat geeft genoeg marge om voor afrondingsfouten van meerdere berekeningen te compenseren.

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.


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 10-12 14:13
.oisyn schreef op dinsdag 23 augustus 2005 @ 14:24:
En als je niet met constante werkt is het verstandig éérst alle vermenigvuldingingen te doen, en daarna pas de delingen (vooropgesteld dat het dan nog wel in een int of long blijft passen, anders zul je uit moeten wijken naar een float of double - liefst een double, aangezien als het niet meer in een int past je meer precisie nodig hebt dan in een float kan).
Voor ints heb je uiteraard gelijk, maar uit m'n hoofd is dat met floats niet het geval. Simpel gezegd: moet je een deling door 2 eerst doen? En een vermenigvuldiging met 0.5? Logisch gezien is dat hetzelfde, en zou het op hetzelfde moment moeten

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 10-12 14:13
Zoijar schreef op dinsdag 23 augustus 2005 @ 15:27:
floats zijn ook niet associatief toch?
Klopt
Maw. het kan voorkomen dat a*b != b*a?
Nee, dat is volgens mij symmetrisch. Associatief is (a*b)*c != a*(b*c).
Vandaar dat je compiler opties hebt voor "strict floating point", dan worden floating point operaties niet van volgorde verwisseld om consistentie tussen units te behouden.
Dat is inderdaad om de gevolgen van niet-associativiteit te negeren. Uit m'n hoofd is het vooral van belang voor Common Sub Expression optimalisaties. Daavoor kan het nuttig zijn om zo'n volgorde te veranderen (als je zeg maar b*c al hebt, en je moet (a*b)*c uitrekenen )

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

MSalters schreef op dinsdag 23 augustus 2005 @ 21:40:
Nee, dat is volgens mij symmetrisch. Associatief is (a*b)*c != a*(b*c).
Ja, dat bedoelde ik ook eigenlijk. Wat ik schreef is commutatief.

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 10-12 14:13
tekno schreef op dinsdag 23 augustus 2005 @ 16:53:
Het gaat hier tot nu toe vooral over delen en vermenigvuldigen.
Bij deze operaties blijft de relatieve fout nog enigzins binnen de perken.
Neem c = a * b , waarbij a een relatieve fout ea heeft en b een relatieve fout eb.
Dan is de relatieve fout van het resultaat (ec) nagenoeg ea + eb
Nemen we nu c = a / b, dan ec = ea - eb.

Nemen we nu echter de - operatie,
dan krijgen we c = a - b geeft ec = a/c * ea - b/c eb
Stel dat c dus ten opzichte van a en b klein is, dan onstaat er een grote relatieve fout in c.
Wat eigenlijk veel ernstiger is.
Klopt allemaal. Numerieke wiskunde probeert dat soort verlies van informatie te voorkomen, en dat is best ingewikkeld.
Hoe ga je dan iets in de trend van (a/b)-(c*d) == constante oplossen in een programmertaal.
Waarin a,b,c en d allen variabelen zijn, de 4 invoerparameters, waar dan 1 uitvoerparameter uitkomt, namelijke een boolean waarde.
Met oplossen bedoel ik dus constateren of dit inderdaad binnen de afrondingsfouten gelijk is aan de constante, of de bewering dus waar is. Analoog aan 1-0.6 == 0.4 -> true/false

Daar ben ik dan meer in geinteresseerd.
Dat doe je met interval wiskunde. Je werkt dan niet met getallen, maar met intervallen [a,a']/[b,b']-[c,c']*[d,d']

Simpel gezegd, [c,c']*[d,d']=[cd,c'd'] en [a,a']/[/b,b']=[a/b',a'/b] (maar dat laatste alleen als b en b'>0)
In interval wiskunde is het antwoord dan simpel. Je eindigt met een interval[x,x'] en als je constante daarin valt, dan is operator== waar.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • Robtimus
  • Registratie: November 2002
  • Laatst online: 19:22

Robtimus

me Robtimus no like you

Rekenen met decimalen op een PC is hoe dan ook rampzalig.
Ooit op de universiteit zelfs geleerd dat (a+b)+c != a+(b+c) zodra er decimalen aan te pas komen. Daar gaan al je wiskundige wetten!

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


  • prototype
  • Registratie: Juni 2001
  • Niet online

prototype

Cheer Bear

Verwijderd schreef op dinsdag 23 augustus 2005 @ 15:10:
Aangezien niemand de vraag stelt, en Janoz er wel heel duidelijk naar zit te vissen:

"waarom mag je twee floats niet met elkaar vergelijken middels de == operator?" ;)
Een floating point is een estimate. Je kan dus niet gelijkheid erop testen.

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 10-12 14:13
Floating points zijn helemaal geen estimates/schattingen. Sterker nog, met IEEE floating point is het resultaat van elke bewerking precies voorgeschreven, en komt er 0 statistiek aan te pas.

Bovendien (maar dat heeft niets met floats te maken) kun je estimates wel vergelijken. De kans dat ik een witte knikker trek, als ik 1 witte heb en twee rode is precies 1/3. Dat is exact hetzelfde als met 2 witte en 4 rode.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Pagina: 1