Alg/.NET Division by zero wordt niet afgevangen bij floats*

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

  • witchdoc
  • Registratie: Juni 2000
  • Laatst online: 11-05 16:57
Visual Basic .NET:
1
2
3
4
5
Try
    Console.WriteLine("Het quotiënt is: " & (intgetal1 / intgetal2))
Catch exception As System.DivideByZeroException
    Console.WriteLine("Delen door nul kan niet.")
End Try


Waarom krijg ik dit niet werkend met een getal anders dan een geheel getal?
Doorspitten van help functie levert niet vet veel op vrees'k.

[ Voor 18% gewijzigd door witchdoc op 22-02-2003 12:48 ]


  • whoami
  • Registratie: December 2000
  • Laatst online: 00:40
Hoezo je krijgt het niet werkend?
Wat werkt er dan niet?

M'n glazen bol is jammer genoeg stuk, dus ik kan je niet zo helpen...
Probeer misschien dit eens:
Welkom in P&W -> Quickstart (update 2/10/2002)

En kom terug met voldoende info.
Succes. ;)

[ Voor 26% gewijzigd door whoami op 22-02-2003 10:34 ]

https://fgheysels.github.io/


Verwijderd

Ik neem je code over. Neem 10 voor intgetal1 en 3 voor intgetal2, dit werkt. Is het probleem soms dat je alleen gehele getallen voor intgetal1/2 mag nemen (dim intgetal1 as integer?)

  • gorgi_19
  • Registratie: Mei 2002
  • Laatst online: 10:01

gorgi_19

Kruimeltjes zijn weer op :9

poohbeer schreef op 22 February 2003 @ 10:29:
code:
1
2
3
4
5
Try
    Console.WriteLine("Het quotiënt is: " & (intgetal1 / intgetal2))
Catch exception As System.DivideByZeroException
    Console.WriteLine("Delen door nul kan niet.")
End Try


Waarom krijg ik dit niet werkend met een getal anders dan een geheel getal?
Doorspitten van help functie levert niet vet veel op vrees'k.
* gorgi_19 vraagt zich af waarom je het op deze manier wil oplossen met een try statement

Visual Basic .NET:
1
2
3
4
5
6
7
8
9
10
Dim dGetal1 as double
Dim dGetal2 as double

...

If dGetal2 = 0 Then
    Console.WriteLine("Delen door nul kan niet.")
Else
    Console.WriteLine("Het quotiënt is: " & (dGetal1 / dGetal2))
End if

[ Voor 11% gewijzigd door gorgi_19 op 22-02-2003 10:46 ]

Digitaal onderwijsmateriaal, leermateriaal voor hbo


  • whoami
  • Registratie: December 2000
  • Laatst online: 00:40
Nou gorgi_19, omdat normaal gezien intgetal2 nooit een 0 zal zijn. Mocht dit ooit toch voorvallen, dan is het een exceptie, een uitzonderlijke situatie zeg maar.
't Is maar hoe je het oplost, maar die methode met de exception vind ik wel mooier. Zo ga je er namelijk vanuit dat intgetal2 eigenlijk geen 0 mag zijn. Nouja.....

Als intgetal1 en intgetal2 vn het type integer zijn, dan kunnen die geen kommagetallen zijn. Het decimale gedeelte wordt dan gewoon 'weggegooid'. Verander je die types naar 'float', dan zal het wel werken.

https://fgheysels.github.io/


  • witchdoc
  • Registratie: Juni 2000
  • Laatst online: 11-05 16:57
Verwijderd schreef op 22 February 2003 @ 10:40:
Ik neem je code over. Neem 10 voor intgetal1 en 3 voor intgetal2, dit werkt. Is het probleem soms dat je alleen gehele getallen voor intgetal1/2 mag nemen (dim intgetal1 as integer?)
Inderdaad.
Excuseer, had misschien iets duidelijker kunnen zijn, maar waarom kan je als getallen enkel gehele getallen nemen? 2,165 / 0 zou toch ook opgevangen moeten worden :?

  • witchdoc
  • Registratie: Juni 2000
  • Laatst online: 11-05 16:57
whoami schreef op 22 February 2003 @ 10:46:
Als intgetal1 en intgetal2 vn het type integer zijn, dan kunnen die geen kommagetallen zijn. Het decimale gedeelte wordt dan gewoon 'weggegooid'. Verander je die types naar 'float', dan zal het wel werken.
Ook als single lukt het niet.

  • whoami
  • Registratie: December 2000
  • Laatst online: 00:40
En wordt dat dan niet opgevangen dan?

Heb je je datatypes al naar float oid gemaakt?

Eneh, gebruik de edit-knop eens.
(En omschrijf je probleem nu eens duidelijk, want anders gaat dit hier giswerk worden)

[ Voor 42% gewijzigd door whoami op 22-02-2003 10:51 ]

https://fgheysels.github.io/


  • gorgi_19
  • Registratie: Mei 2002
  • Laatst online: 10:01

gorgi_19

Kruimeltjes zijn weer op :9

whoami schreef op 22 February 2003 @ 10:46:
Nou gorgi_19, omdat normaal gezien intgetal2 nooit een 0 zal zijn. Mocht dit ooit toch voorvallen, dan is het een exceptie, een uitzonderlijke situatie zeg maar.
't Is maar hoe je het oplost, maar die methode met de exception vind ik wel mooier. Zo ga je er namelijk vanuit dat intgetal2 eigenlijk geen 0 mag zijn. Nouja.....

Als intgetal1 en intgetal2 vn het type integer zijn, dan kunnen die geen kommagetallen zijn. Het decimale gedeelte wordt dan gewoon 'weggegooid'. Verander je die types naar 'float', dan zal het wel werken.
Mjah.. Als je meerdere checks er op loslaat, oftewel meerdere exceptions wil afvangen, dan ben ik het wel met je eens. Alleen in dit specifieke geval, waarin maar in een uitzonderlijk geval een exceptie kan optreden, maakt het imho niet zo veel uit.. :)
Visual Basic .NET:
1
2
3
4
5
6
7
Try
    Console.WriteLine("Het quotiënt is: " & (intgetal1 / intgetal2))
Catch exception As System.DivideByZeroException
    Console.WriteLine("Delen door nul kan niet.")
Catch exception As System.Exception
    Throw exception
End Try

Poohbear: En dit?

[ Voor 19% gewijzigd door gorgi_19 op 22-02-2003 10:53 ]

Digitaal onderwijsmateriaal, leermateriaal voor hbo


  • whoami
  • Registratie: December 2000
  • Laatst online: 00:40
Zeer vreemd inderdaad....
Ik geloofde je niet toen je zei dat die div by 0 niet opgevangen werd bij floats en dus heb het effen uitgetest:

c# code
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
float getal1, getal2, quot;
            
getal1 = Convert.ToSingle (textBox1.Text);
getal2 = Convert.ToSingle (textBox2.Text);
try
{
  quot = getal1 / getal2;
  textBox3.Text = quot.ToString();  
}
catch ( DivideByZeroException ex )
{
  MessageBox.Show ("divide by zero");
}


Als ik hier ervoor zorg dat getal2 0 is, dan wordt de exceptie idd niet opgevangen en krgij ik als resultaat in m'n textBox3 : 'oneindig'.
Dit moet dus betekenen dat 0 niet 0 is, maar 0.000000000000...1 oid...

https://fgheysels.github.io/


  • witchdoc
  • Registratie: Juni 2000
  • Laatst online: 11-05 16:57
gorgi: dat geeft nog steeds: "Het quotiënt is : oneindig"
Wat precies hoort die system.exception te doen trouwens?

  • whoami
  • Registratie: December 2000
  • Laatst online: 00:40
Die exception (DivByZero) wordt gethrowed als er een deling door 0 gebeurd. Aangezien die niet gethrowed wordt, wil dat zeggen dat dat getal != 0 is....

Echter, als ik in m'n bovenstaande code voordat ik de deling doe, volgende regels toevoeg:
code:
1
2
3
4
if( getal2 == 0 )
{
   MessageBox.Show ("getal is 0");
}


Dan krijg ik die msgbox wel te zien....

:?

[ Voor 41% gewijzigd door whoami op 22-02-2003 11:10 ]

https://fgheysels.github.io/


  • gorgi_19
  • Registratie: Mei 2002
  • Laatst online: 10:01

gorgi_19

Kruimeltjes zijn weer op :9

* gorgi_19 volgt het ook niet... Puur wiskundig gezien is het correct; een deling door 0 levert het antwoord oneindig op... Maar dat hij hem gewoon pikt.. :?
Afvangen op 0 lijkt me dan ook de enige mogelijkheid? :?

De andere exceptions pakt gewoon alle overige excepties, mocht iets anders optreden. (bijvoorbeeld je vult karakters in in plaats van cijfers)
Dividing a floating-point value by zero will result in either positive infinity, negative infinity, or Not-a-Number (NaN) according to the rules of IEEE 754 arithmetic. Floating-point operations never throw an exception. For more information, see Single and Double.
Verder net een klein testje gedaan. Volgens de debuggerinformatie wil hij de waarden altijd casten naar double, ook vraag je er niet om.

[ Voor 53% gewijzigd door gorgi_19 op 22-02-2003 11:13 ]

Digitaal onderwijsmateriaal, leermateriaal voor hbo


  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
C# heeft naast float/double ook een decimal type. Deze zou je altijd moeten gebruiken als je moet decimale getallen moet werken.

Bij decimal zal delen door 0 als het goed is wel fout gaan. Wellicht heeft VB .net ook een decimal?

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


  • gorgi_19
  • Registratie: Mei 2002
  • Laatst online: 10:01

gorgi_19

Kruimeltjes zijn weer op :9

mbravenboer schreef op 22 February 2003 @ 11:15:
Bij decimal zal delen door 0 als het goed is wel fout gaan. Wellicht heeft VB .net ook een decimal?
:X ja.. En waarom zeg je dat nu pas? :+
Visual Basic .NET:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
        Dim intgetal1 As Decimal
        Dim intgetal2 As Decimal

        intgetal1 = 5
        intgetal2 = 0

        Try
            Dim intgetal3 As Double = CType((intgetal1 / intgetal2), Double)
            Console.WriteLine(intgetal3)
        Catch e As System.DivideByZeroException
            Console.WriteLine("Deling door 0")
        Catch e As Exception
            Console.WriteLine("Foutje")
        End Try

:P

[ Voor 15% gewijzigd door gorgi_19 op 22-02-2003 11:17 ]

Digitaal onderwijsmateriaal, leermateriaal voor hbo


  • whoami
  • Registratie: December 2000
  • Laatst online: 00:40
mbravenboer schreef op 22 February 2003 @ 11:15:
C# heeft naast float/double ook een decimal type. Deze zou je altijd moeten gebruiken als je moet decimale getallen moet werken.

Bij decimal zal delen door 0 als het goed is wel fout gaan. Wellicht heeft VB .net ook een decimal?


Inderdaad...
Heb je daar ook een verklaring voor? :P

Waarom wordt die IEEE standaard door MS gevolgd voor float/double/etc, en niet voor Decimal?

[ Voor 11% gewijzigd door whoami op 22-02-2003 11:19 ]

https://fgheysels.github.io/


  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
0 is decimal ook echt 0 :P . Een 0 in een float of double is gewoon geen 0 en daarom kan je er dus ook door delen. Decimal vind ik 1 van de zeer goede aspecten van C#: in Java moet je hiervoor een aparte klasse gebruiken (en werkt die in de standaard API geeneens goed).

Ik had net een C# test geschreven, dus ik zet hem nog maar even neer ;) .
code:
1
2
3
4
5
6
7
8
9
10
using System;

class DecimalTest {
  public static void Main(string[] args) {
    decimal x = 5;
    decimal y = 0;
    Console.WriteLine("Result y/x: {0}", y/x);
    Console.WriteLine("Result y/x: {0}", x/y);
  }
}


code:
1
2
3
4
5
6
7
martin@linux:~/tmp/exercises/csharp > mono DecimalTest.exe
Result y/x: 0
 
** (process:22001): WARNING **: unhandled exception System.DivideByZeroException: "Division by zero"
in <0x001cc> System.Decimal:Divide (System.Decimal,System.Decimal)
in <0x00048> System.Decimal:op_Division (System.Decimal,System.Decimal)
in <0x0014a> .DecimalTest:Main (string[])

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
Om je vraag over de IEEE standaard nog duidelijker te beantwoorden: decimal is geen floating point type.

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


  • Rataplan
  • Registratie: Oktober 2001
  • Niet online

Rataplan

per aspera ad astra

En aangezien exceptions in een OO-model handig zijn om te voorkomen dat (bijvoorbeeld) een call naar een property meteen moet worden voorzien van errorchecking (die vergeten wordt, waarna het programma hierboven met Infinity verder zou rekenen, wat nooit [edit:]niet altijd[/edit] de bedoeling kan zijn), zou ik iets als
C#:
1
2
3
4
if(Double.IsInfinity(resultaat) || Double.IsNaN(resultaat)) 
{
    throw new System.DivideByZeroException("fout in module blaat");
}

gebruiken.

[ Voor 30% gewijzigd door Rataplan op 23-02-2003 14:13 . Reden: layout :( typos :(( ]


Journalism is printing what someone else does not want printed; everything else is public relations.


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 04:03
De vraag van de topic starter lijkt me voldoende beantwoord; tijd om off-topic te gaan dus! :P
mbravenboer schreef op 22 February 2003 @ 11:24:
Een 0 in een float of double is gewoon geen 0 en daarom kan je er dus ook door delen.
Waarom is het "gewoon geen 0"? De waarde 0 wordt zelfs op een speciale manier opgeslagen in een IEEE standaard floating point getal.

[ Voor 16% gewijzigd door Soultaker op 22-02-2003 18:35 ]


  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
Soultaker: Waarom is het "gewoon geen 0"? De waarde 0 wordt zelfs op een speciale manier opgeslagen in een IEEE standaard floating point getal.
Ja klopt: ik zat even met m'n gedachte teveel bij 0.1 en dergelijke. 0 heeft eigenlijk zelfs 2 verschillende representaties ;) .

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 09-04 22:08
mbravenboer schreef op 22 February 2003 @ 11:25:
Om je vraag over de IEEE standaard nog duidelijker te beantwoorden: decimal is geen floating point type.
Nee?
Is het dan een fixed point type?

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


  • whoami
  • Registratie: December 2000
  • Laatst online: 00:40
MSalters schreef op 22 February 2003 @ 19:42:
[...]

Nee?
Is het dan een fixed point type?


Ik vraag me dan ook af wat het is....

Dat 0 geen 0 is in een float of double kan ik moeilijk geloven. Volgens die uitleg die gorgi_19 postte, is het gewoon het resultaat bij de deling door 0 die volgens de IEEE standaard oneindig is. Imho heeft dit dus niets te zien met het feit dat 0 niet 0 is. :P

https://fgheysels.github.io/


  • EfBe
  • Registratie: Januari 2000
  • Niet online
decimal is een struct: een 2-ledig getal met de delen: totaal getal aan cijfers en een positie waar de punt (comma) moet staan.

floats en doubles zijn per definitie niet goed op 0 te krijgen, ivm afrondingsfouten (het is t.a.t. een benadering) In de documentatie zul je ook terugvinden dat testen op 0 van floats en doubles niet altijd goed gaat en je ook niet moet doen.

Creator of: LLBLGen Pro | Camera mods for games
Photography portfolio: https://fransbouma.com


  • johnwoo
  • Registratie: Oktober 1999
  • Laatst online: 27-05 19:21

johnwoo

3S-GTE

Even googlen levert deze MSDN pagina op, waar als minimum waarde van een float 1.175494351E–38 wordt opgegeven. Een double kan de 0 al een stuk beter benaderen, maar precies 0 zal niet lukken :)

Enfin, ik denk dat de meeste van jullie dit allang wisten...
het staat ook al 3 keer in dit topic, maar hier is iig een linkje waar de precieze opbouw van een float wordt gegeven

[ Voor 16% gewijzigd door johnwoo op 22-02-2003 21:29 ]

4200Wp ZO + 840Wp ZW + 1680Wp NW | 14xIQ7+ + 1xDS3-L | MTVenusE | HWP1


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 04:03
johnwoo schreef op 22 February 2003 @ 21:28:
Even googlen levert deze MSDN pagina op, waar als minimum waarde van een float 1.175494351E–38 wordt opgegeven. Een double kan de 0 al een stuk beter benaderen, maar precies 0 zal niet lukken :)
Ja hoor, echt wel! Zoek ook maar eens op "IEEE floating point". In denormalized form kun je prima het exacte getal 0 kwijt in een float (of double).
EfBe schreef op 22 February 2003 @ 21:12:
floats en doubles zijn per definitie niet goed op 0 te krijgen, ivm afrondingsfouten (het is t.a.t. een benadering) In de documentatie zul je ook terugvinden dat testen op 0 van floats en doubles niet altijd goed gaat en je ook niet moet doen.
Dezelfde onberedeneerde onzin. Je kunt een heleboel getallen wél exact representeren in een float/double, en berekeningen daarop worden ook exact uitgevoerd. Getallen als "100", "0.5" of "13/16" zijn geen enkel probleem, en uit een vermenigvuldiging van 100 en 0.5 komt dan ook exact 50.

Aangezien gebruik wordt gemaakt van een sommatie van een reeks 2-machten (net zoals in het decimale systeem, eigenlijk) kan niet elk getal exact gerepresenteerd worden, zoals 1/3 bijvoorbeeld. Sterker nog, er zijn meer getallen die niet, dan wel exact gerepresenteerd kunnen worden. Uiteraard treedt er afronding op wanneer het resultaat van een operatie niet gerepresenteerd kan worden. Ook wanneer operaties uitgevoerd worden op getallen die een andere orde van grootte hebben, kunnen onverwachte dingen gebeuren.

Om daarmee te zeggen dat floating point getallen altijd uitsluitend benaderingen zijn, gaat me echter wat te ver. Je moet je de beperkingen ervan realiseren, zonder te overdrijven.

  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
Soultaker: Dezelfde onberedeneerde onzin. Je kunt een heleboel getallen wél exact representeren in een float/double, en berekeningen daarop worden ook exact uitgevoerd.
Kan je daar op rekenen (hehe :+ ) als je een applicatie die ook maar iets met financien doet? Je zou maar een applicatie voor een bank hebben die 0.1 niet helemaal verwerkt zoals dat zou moeten. Mooi vervelend :*) .

Normaal gesproken zou je hiervoor een API moeten gebruiken omdat de meeste talen geen ingebouwd decimal type hebben. C# zet met het decimal type een hele goede trend: het is nu duidelijker waar de floats en doubles wel voor bedoeld zijn en het is niet veel lastiger om te werken met een echt decimal type. Bij een API is dit wel lastiger, zelfs als je operator overloading hebt (zonder dat wordt het helemaal een ramp).

De C# standaard zegt het precies goed:
The decimal type is a 128-bit data type suitable for financial and monetary calculations.
Hoeveel vragen hebben we hier in het verleden al niet langs zien komen over het niet juist functioneren van een float?
Om daarmee te zeggen dat floating point getallen altijd uitsluitend benaderingen zijn, gaat me echter wat te ver. Je moet je de beperkingen ervan realiseren, zonder te overdrijven.
Dat je sommige getallen wel goed kan representeren is irrelevant: zelfs als er maar 1 getal niet goed gerepresenteerd kan worden is je applicatie al niet meer te vertrouwen als je decimale berekeningen had willen bereiken. Hoe groot de verzameling 'fout' gerepresenteerde getallen is bepaald allemaal maar de regelmaat waarmee het fout gaat en maakt het type daarmee niet beter bruikbaar.

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


  • Rataplan
  • Registratie: Oktober 2001
  • Niet online

Rataplan

per aspera ad astra

Soultaker schreef op 22 februari 2003 @ 22:32:
Ja hoor, echt wel! Zoek ook maar eens op "IEEE floating point". In denormalized form kun je prima het exacte getal 0 kwijt in een float (of double).
In dat linkje staat anders
Since the high-order bit of the mantissa is always 1, it is not stored in the number.
En nou is het al weer even geleden dat ik heb leren rekenen, maar 1 is volgens mij onder de meeste omstandigheden groter dan 0 :)


Journalism is printing what someone else does not want printed; everything else is public relations.


  • tomato
  • Registratie: November 1999
  • Niet online
Ok, iedereen heeft een beetje gelijk :P

Floating point getallen worden normaal gesproken in genormaliseerd formaat opgeslagen. Voor 32 bit zal dit iets zijn als:

24 bits Mantissa (bits 0 t/m 22), 8 bits Exponent (bits 23 t/m 30), 1 bits Sign (bit 31).

Merk op dat de 24 bits Mantissa opgeslagen wordt in 23 bits.

Om tot de genormaliseerde vorm te komen wordt de komma verschoven (waarbij steeds de exponent aangepast wordt om de juiste waarde van het getal te handhaven) tot er slechts een cijfer groter dan nul voor de komma staat.
In het tweetallig stelsel is het toevallig zo dat er maar een cijfer groter dan nul bestaat, namelijk 1. Daarom hoeft deze 1 van de Mantissa niet opgeslagen te worden, omdat hij toch altijd 1 is (hence, 23 bits vs 24 bits).

Wat meerder mensen opgemerkt hebben, zoals Rataplan boven mij, kun je met een Mantissa groter of gelijk aan 1 nooit exact 0 representeren, wat je ook in de Exponent of de Sign stopt.

Maar hier komt de truc, zoals Soultaker al opmerkte: De IEEE standaarden houden enkele representaties gereserveerd voor speciale waarden, namelijk alle representaties waarbij de Exponent uit alleen maar 0-en of alleen maar 1-en bestaat.

De speciale waarde waar het ons om gaat is 0, deze wordt gerepresenteerd door een Exponent van alleen maar 0-en en een Mantissa van alleen maar 0-en (wat er dus voor zorgt dat we zelfs twee manieren hebben om precies 0 op te slaan: -0 en +0).

Blijft natuurlijk wel het feit dat er veel andere getallen zijn die niet exact te representeren zijn in een IEEE floating point, dus verder blijven de argumenten overeind.

  • witchdoc
  • Registratie: Juni 2000
  • Laatst online: 11-05 16:57
tomato schreef op 23 February 2003 @ 12:50:
De speciale waarde waar het ons om gaat is 0, deze wordt gerepresenteerd door een Exponent van alleen maar 0-en en een Mantissa van alleen maar 0-en (wat er dus voor zorgt dat we zelfs twee manieren hebben om precies 0 op te slaan: -0 en +0).

Blijft natuurlijk wel het feit dat er veel andere getallen zijn die niet exact te representeren zijn in een IEEE floating point, dus verder blijven de argumenten overeind.
Waarom wordt die speciale waarde dan niet gebruikt als'k deel door 0?!

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 04:03
mbravenboer schreef op 22 februari 2003 @ 22:50:
Dat je sommige getallen wel goed kan representeren is irrelevant: zelfs als er maar 1 getal niet goed gerepresenteerd kan worden is je applicatie al niet meer te vertrouwen als je decimale berekeningen had willen bereiken. Hoe groot de verzameling 'fout' gerepresenteerde getallen is bepaald allemaal maar de regelmaat waarmee het fout gaat en maakt het type daarmee niet beter bruikbaar.
Ik ageerde alleen maar tegen de stelling dat floats per definitie benaderingen zouden zijn, en dat er bij operaties altijd afrondingsfouten optreden. De expressie (666.0 * 2.0 / 4.0 * 4.0 / 2. 0 == 666.0) is gewoon altijd 'waar', ook als je er nog een hele serie operaties achter zet die de nauwkeurigheid niet in gevaar brengen. Er is dus geen reden om te gaan checken op een range van 665.99999 tot 666.00001, ofzo.

Verder heb je helemaal gelijk, maar wat jij beweerde heb ik dan ook nooit ontkend.
Rataplan schreef op 23 February 2003 @ 02:58:
En nou is het al weer even geleden dat ik heb leren rekenen, maar 1 is volgens mij onder de meeste omstandigheden groter dan 0 :)
Ik ga je nog de hint om op een paar zoektermen te Googlen; dat doe ik natuurlijk alleen als op pagina nummer 1 mijn gelijk wordt bewezen. ;) :p Ik merkte duidelijk op dat 0 als gedenormaliseerd nummer wél exact te representeren is. Zie verder tomato's uitleg.
poohbeer schreef op 23 februari 2003 @ 13:24:
Waarom wordt die speciale waarde dan niet gebruikt als'k deel door 0?!
Wat krijg jij eruit dan? Welke "speciale waarde" had je willen hebben?

[ Voor 8% gewijzigd door Soultaker op 23-02-2003 13:42 ]


  • tomato
  • Registratie: November 1999
  • Niet online
poohbeer schreef op 23 February 2003 @ 13:24:
Waarom wordt die speciale waarde dan niet gebruikt als'k deel door 0?!
Dat weet ik zo niet. Ik kan me voorstellen dat die 0 niet echt nul is doordat het een resultaat van een berekening is (bijv in de trand van -1/3 + 1/3).

Maar als ik terug kijk naar je code geef je zelf via een msgbox 0, zonder berekening. Kijk eens wat er gebeurt als je je float op 0 zet in je code, zonder de msgbox.

  • Rataplan
  • Registratie: Oktober 2001
  • Niet online

Rataplan

per aspera ad astra

Soultaker schreef op 23 February 2003 @ 13:37:
Wat krijg jij eruit dan? Welke "speciale waarde" had je willen hebben?
"Infinity", en dan - afhankelijk van de berekening - PositiveInfinity of NegativeInfinity :P

[edit:] Toch even verduidelijken: tuurlijk is er een speciaal geval "0", maar er is ook een speciaal geval "/0", check yer helpfiles. Er kan binnen het kader van de besproken division operator dus gedeeld worden door 0 (!), en dat wil weer zeggen dat het begrip "0" niet op de mathematische manier, maar op een procedurele manier beschouwd moet worden.

Binnen dit topic dan heh :P

[ Voor 44% gewijzigd door Rataplan op 23-02-2003 13:43 ]


Journalism is printing what someone else does not want printed; everything else is public relations.


  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
In de C# ECMA standaard staat een prachtig tabelletje wat het resultaat is als je deelt door -0, +0, NaN, -oneinding en +oneindig. Paragraaf 14.7.2.

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 04:03
Rataplan schreef op 23 February 2003 @ 13:40:
"Infinity", en dan - afhankelijk van de berekening - PositiveInfinity of NegativeInfinity :P
Ok; dat was een stomme vraag. :)

  • tomato
  • Registratie: November 1999
  • Niet online
Rataplan schreef op 23 February 2003 @ 13:40:
"Infinity", en dan - afhankelijk van de berekening - PositiveInfinity of NegativeInfinity :P
Nee, het lijkt me dat we bij een 'echte' 0 een division by zero foutmelding willen krijgen.

Misschien maak je dezelfde fout als gorgi_19:
gorgi_19 schreef op 22 februari 2003 @ 11:09:
Puur wiskundig gezien is het correct; een deling door 0 levert het antwoord oneindig op... Maar dat hij hem gewoon pikt.. :?
Nee, in de wiskunde is het resultaat van een deling door 0 niet gedefinieerd (en dus niet 'oneindig' oid).

  • EfBe
  • Registratie: Januari 2000
  • Niet online
Soultaker schreef op 23 February 2003 @ 13:37:
[...]
Ik ageerde alleen maar tegen de stelling dat floats per definitie benaderingen zouden zijn, en dat er bij operaties altijd afrondingsfouten optreden. De expressie (666.0 * 2.0 / 4.0 * 4.0 / 2. 0 == 666.0) is gewoon altijd 'waar'. (Ook al de compiler dit niet at compiletime uitrekent ;) ).
Je gaat toch nu niet de bewering doen dat jij een float kunt samenstellen met 1/3 erin. Dat is nl. een repeterende breuk. (2/6)/(1/3) hoeft niet 1 te zijn, wanneer je floats gebruikt. Het resultaat in de result-float benadert wellicht 1, maar is het niet. Je MAG daar niet vanuit gaan, dat is wat ik wilde aangeven. De topicstarter gaat daar WEL van uit en dat is dus niet correct. 0.5 opslaan in een float kan idd, de benadering == de waarde die je wilt opslaan, maar t.a.t. mag je logic er niet vanuit gaan dat de float ook EXACT die waarde heeft. Daarom is het gebruik van floats voor berekeningen waarbij uit de resultaten conclusies moeten worden getrokken (dus >= bepaalde waarde etc.) niet verstandig en is het juist wel verstandig andere types te gebruiken, bv decimal. Floats gebruikt bij vertices berekeningen e.d. zijn wellicht wel geoorloofd maar ook daar loop je het risico dat als je floats door een ellenlange berekening haalt, je fout op fout stapelt en bv je 3D mesh niet meer klopt.

Nu mag jij vrolijk code gaan bouwen waarin jij conclusies verbindt aan waarden opgeslagen in floats en doubles, maar ik zou je dat ten zeerste afraden.
[...]
Ik ga je nog de hint om op een paar zoektermen te Googlen; dat doe ik natuurlijk alleen als op pagina nummer 1 mijn gelijk wordt bewezen. ;) :p Ik merkte duidelijk op dat 0 als gedenormaliseerd nummer wél exact te representeren is. Zie verder tomato's uitleg.
Dat is allemaal mooi, maar hoe je die 0 in je float krijgt is vers 2 en leidt niet altijd tot een exacte 0 met die theoretische representatie. (333/999) - ((3*(1/3))/(999*(1/999))) hoeft geen exact 0 te zijn. Dat lijkt wel zo, maar hoeft niet. Is nl. niet gegarandeerd.

[ Voor 2% gewijzigd door EfBe op 23-02-2003 13:51 . Reden: even verduidelijking dat het om de float-logic gaat en niet om theoretische wiskunde ]

Creator of: LLBLGen Pro | Camera mods for games
Photography portfolio: https://fransbouma.com


  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
Overigens is de C# standaard op veel punten erg goed en duidelijk: er is bijvoorbeeld ook een mooi tabelletje van de prioriteiten van expressies in plaats van een brakke grammatica waar je dat maar uit moet zien te halen (zoals in de Java Language Specification).

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


  • Rataplan
  • Registratie: Oktober 2001
  • Niet online

Rataplan

per aspera ad astra

tomato schreef op 23 February 2003 @ 13:48:
[...]

Nee, het lijkt me dat we bij een 'echte' 0 een division by zero foutmelding willen krijgen.

Misschien maak je dezelfde fout als gorgi_19:


[...]

Nee, in de wiskunde is het resultaat van een deling door 0 niet gedefinieerd (en dus niet 'oneindig' oid).
Die fout maak ik niet, ik beschouw dit topic vanuit het perspectief van een .NET-programmeur. En die krijgt na een deling door 0 (type double or float) een Infinity-value voor zijn kiezen.

[edit:]En als je een foutmelding wilt dan overload je de division voor die twee types maar :)

[ Voor 11% gewijzigd door Rataplan op 23-02-2003 13:54 ]


Journalism is printing what someone else does not want printed; everything else is public relations.


  • tomato
  • Registratie: November 1999
  • Niet online
Rataplan schreef op 23 February 2003 @ 13:51:
Die fout maak ik niet, ik beschouw dit topic vanuit het perspectief van een .NET-programmeur. En die krijgt na een deling door 0 (type double or float) een Infinity-value voor zijn kiezen.
Maar er werd gevraagd wat je wilt hebben en dat lijkt me toch wel een foutmelding.

  • Rataplan
  • Registratie: Oktober 2001
  • Niet online

Rataplan

per aspera ad astra

tomato schreef op 23 February 2003 @ 13:56:
[...]

Maar er werd gevraagd wat je wilt hebben en dat lijkt me toch wel een foutmelding.
Ik moet eerlijk bekennen dat ik van deze delingsquirk in .NET niet op de hoogte was, maar, zoals ik al editte, met een simpele overload kan je die foutmelding forceren.

Echter, zoals Efbe al schreef:
Nu mag jij vrolijk code gaan bouwen waarin jij conclusies verbindt aan waarden opgeslagen in floats en doubles, maar ik zou je dat ten zeerste afraden.
Het is wat drastisch geformuleerd, maar het klopt wel. Floating points zijn per definitie niet accuraat.

Verder hangt het natuurlijk volledig van je app af wat je wilt hebben. De property lengte van een object met oppervlakte 1 en breedte 0 mag van mij bijvoorbeeld best "infinity" teruggeven, tenzij die waarde vervolgens in een plotter gegooid wordt :X


Journalism is printing what someone else does not want printed; everything else is public relations.


  • EfBe
  • Registratie: Januari 2000
  • Niet online
Ik denk dat mensen niet met een theoretische wiskunde-bril naar het probleem moeten kijken. Floats hebben 32 bits, en daar past niet alles in, daardoor zijn ze niet zo accuraat als men verwacht. In theorie zou het moeten kloppen, in de praktijk echter lukt dat niet. Veelal zijn die afrondingsfouten niet zo erg, maar soms wel en het is dan zaak rekening te houden met de limieten van de float als datatype, ookal zegt de theorie dat die limieten er eigenlijk niet zouden moeten zijn :)

Creator of: LLBLGen Pro | Camera mods for games
Photography portfolio: https://fransbouma.com


  • witchdoc
  • Registratie: Juni 2000
  • Laatst online: 11-05 16:57
EfBe schreef op 23 February 2003 @ 13:48:
[...]

Je gaat toch nu niet de bewering doen dat jij een float kunt samenstellen met 1/3 erin. Dat is nl. een repeterende breuk. (2/6)/(1/3) hoeft niet 1 te zijn, wanneer je floats gebruikt. Het resultaat in de result-float benadert wellicht 1, maar is het niet. Je MAG daar niet vanuit gaan, dat is wat ik wilde aangeven. De topicstarter gaat daar WEL van uit en dat is dus niet correct. 0.5 opslaan in een float kan idd, de benadering == de waarde die je wilt opslaan, maar t.a.t. mag je logic er niet vanuit gaan dat de float ook EXACT die waarde heeft.
uh :?

Ik ga helemaal niet van breuken uit, ik geef in mijn console venstertje 2 getallen in. Beide zijn perfect gedefiniëerd en dus niet 1/3 ofzo!

Wat ik gewoon niet snap is waarom je 0 niet simpelweg in een single (aka float) ingepropt krijgt. 'k bedoel, alle bitjes 0 maken is toch best makkelijk? Daar hebben we die EBCDIC shit (of was het nou die complement methodes?) enzo toch voor?

Welk nut heeft een single en double dan als je er niet eens een deling door 0 mee kan maken? Is toch echt een bewerking die wel eens wil voorkomen. Dus moet je altijd maar die decimal gaan gebruiken? Maar als deze de enige is die goed met divide by 0 overweg kan, waarom gebruikt men dan die float nog?

Want als ik dit goed snap kan'k voortaan maar beter overal waar ik een single of double gebruik een decimal in de plaats gebruiken?

Hoe bekend is dit alles trouwens? Want 'k vind het best wel vaag dat zowel mijn (avondschool) lerares vb.net (ok, ze heeft er meer moeite mee dan wij) maar ook haar collega die full time programmeershit geeft, dit niet weten.
Zal'k misschien toch maar elders school gaan zoeken? :/

[ Voor 10% gewijzigd door witchdoc op 24-02-2003 10:00 ]


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 10:51

.oisyn

Moderator Devschuur®

Demotivational Speaker

EfBe schreef op 23 February 2003 @ 13:48:
[...]

Je gaat toch nu niet de bewering doen dat jij een float kunt samenstellen met 1/3 erin.


dat zei hij eerder al:
Soultaker schreef op 22 February 2003 @ 22:32:
[...]
Aangezien gebruik wordt gemaakt van een sommatie van een reeks 2-machten (net zoals in het decimale systeem, eigenlijk) kan niet elk getal exact gerepresenteerd worden, zoals 1/3 bijvoorbeeld. Sterker nog, er zijn meer getallen die niet, dan wel exact gerepresenteerd kunnen worden. Uiteraard treedt er afronding op wanneer het resultaat van een operatie niet gerepresenteerd kan worden. Ook wanneer operaties uitgevoerd worden op getallen die een andere orde van grootte hebben, kunnen onverwachte dingen gebeuren.

Om daarmee te zeggen dat floating point getallen altijd uitsluitend benaderingen zijn, gaat me echter wat te ver. Je moet je de beperkingen ervan realiseren, zonder te overdrijven.

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.


  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
poohbeer schreef op 24 February 2003 @ 09:56:
[...]
Welk nut heeft een single en double dan als je er niet eens een deling door 0 mee kan maken? Is toch echt een bewerking die wel eens wil voorkomen. Dus moet je altijd maar die decimal gaan gebruiken? Maar als deze de enige is die goed met divide by 0 overweg kan, waarom gebruikt men dan die float nog?
Je kan er juist wel een deling door 0 mee doen. Maar ik snap niet zo wat het echte probleem nou is. Het is gewoon gedocumenteerd dat als je bij een float of double door 0 deelt dat je geen Exception krijgt maar gewoon Infinite terug krijgt. Als je graag wil controleren op delen door 0 zul je dat niet met Exceptions moeten doen maar gewoon even
C:
1
2
3
4
5
6
7
8
if( waarde == 0 )
{
    //hier wat dingen doen
}
else
{
    //Je mag niet door 0 delen
}

En dat je meteen maar geen floats moet gebruiken omdat het een benadering van het getal is dat moet je ook niet al te serieus nemen. In de meeste gevallen is een minimale afwijking helemaal geen probleem. Het is natuurlijk wel slim om er even over na te denken voordat je floats gaat gebruiken. Want in gevallen zoals bij banken waarbij de uitkomst natuurlijk niet zomaar even wat mag afwijken is het inderdaad niet slim om floats te gebruiken.

[ Voor 4% gewijzigd door Woy op 24-02-2003 10:48 ]

“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.”

Pagina: 1