[AS2] Floats vergelijken

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

  • Sihaya
  • Registratie: Juni 2001
  • Niet online

Sihaya

Pasfoto:

Topicstarter
Hallo Tweakers,

Wanneer ik in Actionscript 2 draaiend onder Flash 9 het volgende stukje probeer uit te voeren:

code:
1
2
3
4
5
6
var getal1 = 1.4;
var getal2 = 0.9;
        
getal1 = getal1 - 0.5;
        
trace("Uitkomst: " + getal1 + " == " + getal2 + " -- " + String(getal1 == getal2));


krijg ik als resultaat dat deze getallen niet gelijk zijn:


code:
1
Uitkomst: 0.9 == 0.9 -- false



Nu weet ik dat equality en floating point getallen nooit zo'n goed idee is i.v.m. afronding, maar de code waaruit dit komt staat hier helaas vol mee. Daarnaast zou ik verwachten dat de string versies van de getallen bij een afrondingsprobleem ook niet gelijk zijn.

Iemand enig idee waar dit door komt of wellicht een workaround?

signature has expired


Acties:
  • 0 Henk 'm!

  • zwippie
  • Registratie: Mei 2003
  • Niet online

zwippie

Electrons at work

Wat gebeurt er als je getal1 en getal2 als Number declareert?
code:
1
2
var getal1:Number = 1.4;
var getal2:Number = 0.9

How much can you compute with the "ultimate laptop" with 1 kg of mass and 1 liter of volume? Answer: not more than 10^51 operations per second on not more than 10^32 bits.


Acties:
  • 0 Henk 'm!

  • Puc van S.
  • Registratie: Maart 2002
  • Laatst online: 15:53
gebruik ipv String(getal1 == getal2)

code:
1
getal1.toString() == getal2.toString()

[http://www.okbreijnen.nl] [Overwatch] [Cennahysh]


Acties:
  • 0 Henk 'm!

  • Patriot
  • Registratie: December 2004
  • Laatst online: 13:05

Patriot

Fulltime #whatpulsert

M1lamb3r schreef op maandag 29 december 2008 @ 16:37:
gebruik ipv String(getal1 == getal2)

code:
1
getal1.toString() == getal2.toString()
Dat is wat anders. Hij wil de uitkomst van de vergelijking als string hebben, niet de twee nummers als string vergelijken.

Acties:
  • 0 Henk 'm!

Verwijderd

Patriot schreef op maandag 29 december 2008 @ 16:39:
Dat is wat anders. Hij wil de uitkomst van de vergelijking als string hebben, niet de twee nummers als string vergelijken.
Hij bedoelt dat als de toString() van 2 floats gelijk zijn dat dan de floats ook gelijk zijn.

Acties:
  • 0 Henk 'm!

  • McVirusS
  • Registratie: Januari 2000
  • Nu online
Je kan het op meerdere manieren oplossen, 2 opties:

1. getal1.toString() == getal2.toString()
2. getal1 eq getal2

trace("Uitkomst: " + getal1 + " == " + getal2 + " -- " + String(getal1 eq getal2));
trace("Uitkomst: " + getal1 + " == " + getal2 + " -- " + String(getal1.toString() == getal2.toString()));

Traced allebei: Uitkomst: 0.9 == 0.9 -- true

Converten naar Number werkt niet zwippie.

Ook een leuke die ook werkt 8)7

trace(parseFloat(getal1.toString()) == parseFloat(getal2.toString()));

Acties:
  • 0 Henk 'm!

  • TheBorg
  • Registratie: November 2002
  • Laatst online: 23-09 17:18

TheBorg

Resistance is futile.

In het echt is getal1 dan ook 0.8999999999999999. Publish maar eens als AS3.
Numbers vergelijken met == is nooit een goed idee.

Acties:
  • 0 Henk 'm!

  • McVirusS
  • Registratie: Januari 2000
  • Nu online
Als je niet typecast kan je trouwens ook gewoon parseFloat gebruiken op een Number.

Acties:
  • 0 Henk 'm!

  • Sihaya
  • Registratie: Juni 2001
  • Niet online

Sihaya

Pasfoto:

Topicstarter
zwippie schreef op maandag 29 december 2008 @ 16:35:
Wat gebeurt er als je getal1 en getal2 als Number declareert?
Dezelfde uitkomst helaas, ook als ik Number(getal1) == Number(getal2) gebruik.
M1lamb3r schreef op maandag 29 december 2008 @ 16:37:
gebruik ipv String(getal1 == getal2)

code:
1
getal1.toString() == getal2.toString()
Thanks, dit werkt. Toch vind ik het wel vreemd dat er een string conversie voor nodig is.
TheBorg schreef op maandag 29 december 2008 @ 16:47:
In het echt is getal1 dan ook 0.8999999999999999. Publish maar eens als AS3.
Numbers vergelijken met == is nooit een goed idee.
Aha, dit verklaart een hoop. Je hebt gelijk dat dit geen goed idee is, helaas was de maker van het programma dat ik aanpas hiervan niet op de hoogte :'(.


Bedankt voor de reacties.

[ Voor 27% gewijzigd door Sihaya op 29-12-2008 16:54 ]

signature has expired


Acties:
  • 0 Henk 'm!

  • TheBorg
  • Registratie: November 2002
  • Laatst online: 23-09 17:18

TheBorg

Resistance is futile.

Bij een bank doen ze alle bedragen x100 zodat er geen centen meer zijn. Aan het eind van de berekeningen wordt er weer gedeeld door 100. Dit zou je hier ook kunnen doen.

Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Zie ook:
Floats (ook wel drijvende komma of zwevende komma getallen)
Floats en afronding
Wikipedia: Floating point - Accuracy problems

Korte samenvatting: als je floats gaat vergelijken, hou dan rekening met een marge (de gewenste significantie is natuurlijk bepalend voor die marge)

[ Voor 79% gewijzigd door RobIII op 29-12-2008 17:13 ]

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


Acties:
  • 0 Henk 'm!

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 13-09 00:05

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


Acties:
  • 0 Henk 'm!

  • Sihaya
  • Registratie: Juni 2001
  • Niet online

Sihaya

Pasfoto:

Topicstarter
Dit snapte ik op zich al, maar ik vind het vreemd dat de string representatie in dit geval 0.9 gaf i.p.v. 0.8999999999999999. Er staat in de documentatie van AS2 nergens dat de toString() al een rouding uitvoert of iets dergelijks.

signature has expired


Acties:
  • 0 Henk 'm!

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 13-09 00:05
Waarom? 0.89999999999 is hetzelfde als 0.9. En ook hetzelfde als 0.89999999998. toString moet één van de vele decimale representatie kiezen die overeenkomt met de binaire.

Rounding daarentegen is bijvoorbeeld het afronden van 0.89 naar 0.9 of 1. Het verschil tussen loss of precision en rounding is dat (0.9 - 0.89999999999) == 0 maar (0.9 - 0.89) > 0.

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


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 22-09 16:37

.oisyn

Moderator Devschuur®

Demotivational Speaker

Floats moet je idd niet met a==b vergelijken. Feitelijk wil je weten of ze dicht bij elkaar liggen, dus met abs(a-b) < epsilon, waarbij je met epsilon bepaalt wat de marge is. Echter is dit onhandig, omdat a en b heel groot of juist heel klein kunnen zijn, waardoor je geen constante epsilon kunt gebruiken. Eigenlijk wil je epsilon schalen naar de orde van grootte van a en b, waardoor de vergelijking wordt:
abs(a-b) < epsilon * (abs(a) + abs(b)).

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.

Pagina: 1