[Java] Rare return waarde

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

  • polu
  • Registratie: December 2002
  • Laatst online: 23-01 08:45
Ik was bezig met het schrijven van een simpele code in Java, maar kwam een merkwaardig probleem tegen.

Java:
1
2
3
4
public double test()
    {
        return 50 * 1.2;
    }

Waarom geeft dit gewoon de waarde 60.0

Java:
1
2
3
4
public double test()
    {
        return 50 * 1.1;
    }

Maar dit de waarde 55.00000000000001 :X

Is dat normaal? Of heb ik een vage bug in Bluej of de JDK van Linux?

jboelen.nl


  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 13:10

Creepy

Tactical Espionage Splatterer

Dat is normaal. Een double kan nu eenmaal niet alle willekeurige waarden representeren en gebruikt dan ook altijd een benadering van een getal. Zie bijv. http://www.hal-pc.org/~cl...er-arithmetic/floats.html

[ Voor 20% gewijzigd door Creepy op 09-10-2006 17:54 ]

"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


  • Gonadan
  • Registratie: Februari 2004
  • Laatst online: 14:22

Gonadan

Admin Beeld & Geluid, Harde Waren
[google=floating point accuracy]

Het is een algemeen bekend probleem.
Het komt in meerdere (zo niet alle) programmeertalen voor :)

Look for the signal in your life, not the noise.

Canon R6 | RF 24-70 f/2.8 L | 50 f/1.8 STM | 430EX II
Sigma 85 f/1.4 Art | 100-400 Contemporary
Zeiss Distagon 21 f/2.8


  • Cuball
  • Registratie: Mei 2002
  • Laatst online: 03-02 20:14
omdat java waarschijnlijk 1.2 als double niet perfect binair kan voorstellen.

"Live as if you were to die tomorrow. Learn as if you were to live forever"


  • polu
  • Registratie: December 2002
  • Laatst online: 23-01 08:45
Ah, op die manier, weer wat geleerd. :)
Hartelijk dank voor de snelle reacties. _/-\o_

jboelen.nl


  • JKVA
  • Registratie: Januari 2004
  • Niet online

JKVA

Design-by-buzzword fanatic

Normaal gesproken wil je getallen enigszins afgerond op je scherm hebben. In simpele gevallen is het ook totaal niet boeiend dat die fout erin zit omdat het toch afgerond wordt.

Als je echter wel op je waarden moet kunnen bouwen, dan is het aan te raden om de BigDecimal klasse te gebruiken. BIjvoorbeeld in financiele systemen. Of elk ander systeem waarin de waarden correct moeten zijn.

Fat Pizza's pizza, they are big and they are cheezy


  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
JKVA schreef op maandag 09 oktober 2006 @ 19:33:
Normaal gesproken wil je getallen enigszins afgerond op je scherm hebben. In simpele gevallen is het ook totaal niet boeiend dat die fout erin zit omdat het toch afgerond wordt.

Als je echter wel op je waarden moet kunnen bouwen, dan is het aan te raden om de BigDecimal klasse te gebruiken. BIjvoorbeeld in financiele systemen. Of elk ander systeem waarin de waarden correct moeten zijn.
Of als je nooit preciezer als centen hoeft te rekenen gewoon in een Integer of Long opslaan.

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


  • BestTested!
  • Registratie: Oktober 2003
  • Laatst online: 12-02 22:19
rwb schreef op maandag 09 oktober 2006 @ 19:52:
[...]

Of als je nooit preciezer als centen hoeft te rekenen gewoon in een Integer of Long opslaan.
offtopic:
Volgens mij was het zo, dat wanneer je met geld rekent, je minimaal tot 6 decimalen moet werken (dus 2 voor centen, 4 extra) om afrondingsfouten zo klein mogelijk te houden. Wettelijk vastgesteld.

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Gonadan schreef op maandag 09 oktober 2006 @ 17:53:
[google=floating point accuracy]

Het is een algemeen bekend probleem.
Het komt in meerdere (zo niet alle) programmeertalen voor :)
Het is geen "probleem" maar gewoon gedrag inherent aan het gebruik van een IEEE floating point...
Cuball schreef op maandag 09 oktober 2006 @ 17:53:
omdat java waarschijnlijk 1.2 als double niet perfect binair kan voorstellen.
...en dat gedrag hang niet samen met java alleen maar met alle programmeertalen (compilers) die IEEE floating points gebruiken.
rwb schreef op maandag 09 oktober 2006 @ 19:52:
[...]
Of als je nooit preciezer als centen hoeft te rekenen gewoon in een Integer of Long opslaan.
Ik weet niet hoe het in Java zit, maar de meeste talen hebben anno 2006 wel een "currency" datatype of iets soortgelijks (en dat kan goed, zoals JKVA al aangeeft, de BigDecimal classe zijn). IMHO is dat netter dan "in centen" opslaan.
BestTested! schreef op maandag 09 oktober 2006 @ 20:48:
[...]

offtopic:
Volgens mij was het zo, dat wanneer je met geld rekent, je minimaal tot 6 decimalen moet werken (dus 2 voor centen, 4 extra) om afrondingsfouten zo klein mogelijk te houden. Wettelijk vastgesteld.
Heb je daar een bron van?

[ Voor 39% gewijzigd door RobIII op 09-10-2006 21: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


  • cowgirl
  • Registratie: November 2000
  • Laatst online: 18-12-2025
RobIII schreef op maandag 09 oktober 2006 @ 21:21:
[...]

Heb je daar een bron van?
Vziw is dat een regel uit de driehoeksberekening, dus uit de tijd dat bijvoorbeeld van guldens naar francen via de euro omgerekend moest worden. In dat geval moesten alle tussentotalen tot 6 posities achter de komma precies zijn en mocht pas op het einde afgerond worden.
In de praktijk merkte je eigenlijk het verschil niet, behalve bij grotere bedragen in Lire's.
Driehoeksberekening
Wettelijk is vastgelegd dat de wisselkoersen van de euro naar de verschillende nationale muntsoorten steeds zes significante cijfers zullen bevatten. Eén euro zou bijvoorbeeld gelijk kunnen zijn aan NLG 2.19181. Om van guldens naar euro's te gaan, moet dan gedeeld worden door 2,19181; het is niet toegestaan om de inverse daarvan te nemen (met zes significante cijfers: 0,456244) en daar mee te vermenigvuldigen. Honderdduizend gulden is in dit voorbeeld dus gelijk aan (100.000/2,19181 =) 45.624,39 euro, en niet aan (100.000 * 0,456244 =) 45.624,40 euro.

[ Voor 39% gewijzigd door cowgirl op 09-10-2006 22:02 . Reden: bron toegevoegd ]


Verwijderd

BestTested! schreef op maandag 09 oktober 2006 @ 20:48:
offtopic:
Volgens mij was het zo, dat wanneer je met geld rekent, je minimaal tot 6 decimalen moet werken (dus 2 voor centen, 4 extra) om afrondingsfouten zo klein mogelijk te houden. Wettelijk vastgesteld.
Bijna goed. ;) Bij valuta conversies moet je met min. 5 decimalen rekenen, maar bij gewone financiele transacties zonder conversie is 2 decimalen prima.
Sterker nog, bij bv. BTW berekeningen moet je 't per boekingsregel uitrekenen en direct op 2 decimalen afronden. Een order van een paar honderd regels mag je dus niet eerst totaliseren en dan (gesplitst naar BTW-groep) de BTW berekenen. Ook al zou dat precieser en 'netter' zijn...

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Verwijderd schreef op maandag 09 oktober 2006 @ 22:41:
[...]
Bijna goed. ;) Bij valuta conversies moet je met min. 5 decimalen rekenen, maar bij gewone financiele transacties zonder conversie is 2 decimalen prima.
Sterker nog, bij bv. BTW berekeningen moet je 't per boekingsregel uitrekenen en direct op 2 decimalen afronden. Een order van een paar honderd regels mag je dus niet eerst totaliseren en dan (gesplitst naar BTW-groep) de BTW berekenen. Ook al zou dat precieser en 'netter' zijn...
Toevallig werk ik op het moment bij een bedrijf wat pin-terminals maakt en weet dus dat in pin-terminals alles gewoon in centen gerekend wordt. Het scheelt natuurlijk dat je daar geen delingen uitvoert en dus geen precisie verliest.

Het is dus belangrijk om van te voren duidelijk op te stellen wat de eisen aan je systeem zijn en of het acceptabel is dat je precisie verliest en op welke manier je dat zou kunnen opvangen.

“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