1. Dashboard
  2. Forum
    1. Unerledigte Themen
  3. Mitglieder
    1. Letzte Aktivitäten
    2. Benutzer online
    3. Team-Mitglieder
    4. Trophäen
    5. Mitgliedersuche
  4. Tutorial Bereich
  • Anmelden
  • Registrieren
  • Suche
Dieses Thema
  • Alles
  • Dieses Thema
  • Dieses Forum
  • Seiten
  • Forum
  • Lexikon
  • Erweiterte Suche
  1. Informatik Forum
  2. Webmaster & Internet
  3. Entwicklung

rechnet sun-jdk falsch?

  • Kampi
  • 4. April 2006 um 18:51
  • Unerledigt
  • Kampi
    27
    Kampi
    Mitglied
    Reaktionen
    193
    Punkte
    7.828
    Beiträge
    1.468
    • 4. April 2006 um 18:51
    • #1

    ich habe ein package 'calculator' mit einer klasse 'CalculatorFunctions' und einigen methoden, die sehr einfach gestrickt sind. in folgender art und weise:

    Code
    public double subtract(double number1, double number2) {
            return number1 - number2;
        }


    diese werden in einer testbench aufgerufen:

    Code
    public void testSubtract1() {                
                double myvalue=cf.subtract(3.2, 2.5);
                System.out.println("Subtract1: " + myvalue);
                assertTrue(myvalue == 0.7);
            }


    das objekt 'cf' wurde zuvor angelegt:

    Code
    calculator.CalculatorFunctions cf = new calculator.CalculatorFunctions();


    beim 'println' kommt nun folgendes raus:

    Code
    Subtract1: 0.7000000000000002


    eine ebenso einfach gestrickte methode 'multiply' liefert zb bei 'multiply(3.4,8.2)' den wert 'Multiply1: 27.879999999999995'

    das ganze passiert mit sun-jdk 1.5.0_06 unter x86/win2k

    was mache ich falsch?

    Willfähriges Mitglied des Fefe-Zeitbinder-Botnets und der Open Source Tea Party.

  • Plantschkuh!
    24
    Plantschkuh!
    Mitglied
    Reaktionen
    163
    Punkte
    6.173
    Beiträge
    1.181
    • 4. April 2006 um 19:12
    • #2
    Zitat von Kampi

    was mache ich falsch?


    Du rufst dir nicht das minimale Grundwissen in Erinnerung, das du in Grundzüge der Informatik über Numerik erworben hast.
    Die Kurzfassung: Computer können nicht rechnen, und wenn es um Subtraktion geht, sind die Ergebnisse ganz besonders phantasievoll frei erfunden.

    *plantsch*

  • klausi
    16
    klausi
    Mitglied
    Reaktionen
    24
    Punkte
    2.564
    Beiträge
    481
    • 4. April 2006 um 19:15
    • #3

    du machst gar nix falsch - es liegt an den Gleitkommazahlen, die du verwendest.
    die werden intern aufgeteilt in mantisse und exponent - daurch geht information verloren, weil es keine absolute genauigkeit gibt. deshalb kann es manchmal zu absurden ergbenissen kommen.
    siehe auch http://de.wikipedia.org/wiki/Gleitkomm…kommaarithmetik

  • Filz
    9
    Filz
    Mitglied
    Punkte
    815
    Beiträge
    150
    • 4. April 2006 um 19:20
    • #4

    dein Fehler - du rechnest im Kopf nicht binär, solltest du dir langsam angewöhnen:
    http://en.wikipedia.org/wiki/Floating_…_floating-point

    Demo

  • Kampi
    27
    Kampi
    Mitglied
    Reaktionen
    193
    Punkte
    7.828
    Beiträge
    1.468
    • 4. April 2006 um 20:29
    • #5

    okay, alles klar. hab zwar an die interne darstellung gedacht dies aber anscheinend verworfen, weil ich mich zu stark an den ppc/blackdown bug den ich vor kurzem hatte erinnert fuehlte. what ever.

    was ist aber nun eurer meinung nach die sinnvollste moeglichkeit einen vergleich durchzufuehren? wenn ich auf 'float' caste, dann funktionierts. in dem fall werd ich auch keine probleme durch den cast bekommen, aber wie macht mans wenn man von java ahnung hat?

    Willfähriges Mitglied des Fefe-Zeitbinder-Botnets und der Open Source Tea Party.

  • Swoncen
    22
    Swoncen
    Mitglied
    Reaktionen
    1
    Punkte
    5.331
    Beiträge
    993
    • 4. April 2006 um 20:51
    • #6

    Ich weiß nicht wie oft ich schon float/real/double Werte miteinander verglichen habe. Allerhöchstens mit Toleranz. Vielleicht ist das für dich auch akzeptabel?

    640K ought to be enough for anybody. :eek2:

  • Trux
    12
    Trux
    Mitglied
    Reaktionen
    26
    Punkte
    1.396
    Beiträge
    274
    • 4. April 2006 um 21:22
    • #7
    Zitat von Kampi

    wenn ich auf 'float' caste, dann funktionierts.

    das stimmt vielleicht in diesem fall, aber dafür stimmen dann andere rechnungen wieder nicht. ein cast auf float bringt rein gar nichts. am ehesten funktionierts noch wenn du eine kleine toleranz akzeptierst.

  • Wolfibolfi
    37
    Wolfibolfi
    Mitglied
    Reaktionen
    186
    Punkte
    14.936
    Beiträge
    2.942
    • 5. April 2006 um 10:33
    • #8

    Kurz gesagt: Nur Halbe, Viertel, Achtel, Sechzehntel (...) und diverse Zusammensetzungen sind genau darstellbar. 0.7 kriegst du nicht genau hin.

    Am einfachsten mit Toleranz vergleichen, statt if (x=0.7) schreibst halt if (abs(x-0.7) < 0.0000001) oder so.

    In einen FBO rendern ist wie eine Schachtel Pralinen - man weiß nie, was man kriegt.

  • stormcrow
    6
    stormcrow
    Mitglied
    Punkte
    360
    Beiträge
    72
    • 5. April 2006 um 22:04
    • #9

    jup, gleitkommazahln sollt man nie exakt vergleichn sondern immer mit einem kleinen delta.

    I came here to chew gum and kick ass, and I'm all out of gum...

  • thanatos5
    8
    thanatos5
    Mitglied
    Punkte
    625
    Beiträge
    116
    • 16. April 2006 um 03:56
    • #10

    sinnvoll ist es fl oder double zu runden und dann erst zu vergleichen und die abweichung einbeziehen beim vergleichen

    "Am Anfang war ich, und dann kamst du,
    und nun wird mir schlecht :-)):devil:
    "

  • Swoncen
    22
    Swoncen
    Mitglied
    Reaktionen
    1
    Punkte
    5.331
    Beiträge
    993
    • 16. April 2006 um 11:50
    • #11

    zu runden und dann erst zu vergleichen? was ist z.B. mit 3,48 und 3,51? Das wär nach dem Runden dann 3 und 4...

    640K ought to be enough for anybody. :eek2:

  • Kornuun
    4
    Kornuun
    Mitglied
    Punkte
    140
    Beiträge
    28
    • 16. April 2006 um 12:03
    • #12

    nein, du rundest natürlich nicht auf 0 Kommastellen sondern z.B. auf 5 Kommastellen genau! damit bleibt 3.48 auch 3.48, aber 1.234567 ist dann halt1.23457

  • Swoncen
    22
    Swoncen
    Mitglied
    Reaktionen
    1
    Punkte
    5.331
    Beiträge
    993
    • 16. April 2006 um 12:48
    • #13

    Was hätte das für einen Vorteil?

    640K ought to be enough for anybody. :eek2:

  • Wolfibolfi
    37
    Wolfibolfi
    Mitglied
    Reaktionen
    186
    Punkte
    14.936
    Beiträge
    2.942
    • 16. April 2006 um 19:58
    • #14

    Das funktioniert eben nicht. Das Rundungsergebnis wird in genausoeinem Float-Register gespeichert, wie die Zahl vorher, da gibts auch dieselben Probleme.
    Mit Toleranz vergleichen, oder nen Integer zu einer Fixkommazahl umbauen, das kann funktionieren.

    In einen FBO rendern ist wie eine Schachtel Pralinen - man weiß nie, was man kriegt.

  • thanatos5
    8
    thanatos5
    Mitglied
    Punkte
    625
    Beiträge
    116
    • 16. April 2006 um 20:59
    • #15
    Zitat von Wolfibolfi

    Das funktioniert eben nicht. Das Rundungsergebnis wird in genausoeinem Float-Register gespeichert, wie die Zahl vorher, da gibts auch dieselben Probleme.
    Mit Toleranz vergleichen, oder nen Integer zu einer Fixkommazahl umbauen, das kann funktionieren.



    warum nicht ich meine eine zwangs casten oder halt eine abrundung machen bspw nach 3 stellen nach den kommer mit round() .

    "Am Anfang war ich, und dann kamst du,
    und nun wird mir schlecht :-)):devil:
    "

  • Paulchen
    1
    Paulchen
    Gast
    • 16. April 2006 um 21:59
    • #16
    Zitat von thanatos5

    warum nicht ich meine eine zwangs casten oder halt eine abrundung machen bspw nach 3 stellen nach den kommer mit round() .

    ja, und das wird dann wieder ungenau gespeichert, sodass die achte stelle nach dem komma nicht passt. vielleicht solltest du dich mal damit befassen, wie ein computer gleitkommazahlen speichert.

  • Wolfibolfi
    37
    Wolfibolfi
    Mitglied
    Reaktionen
    186
    Punkte
    14.936
    Beiträge
    2.942
    • 16. April 2006 um 22:33
    • #17

    Tja, wenn du binär rundest, dann funktionierts. Da müsstest du aber 0,8(10) auf 0,75(10) runden, weil da 0,11001...(2) auf 0,11(2) gerundet wird.

    Und gefühlsmäßig ist 0,8 zwar ein gerundetes 0.75, im Binärsystem ists aber umgekehrt. Denk nicht im Dezimalsystem, das bringt dir nix.

    In einen FBO rendern ist wie eine Schachtel Pralinen - man weiß nie, was man kriegt.

  • Spockman
    5
    Spockman
    Mitglied
    Punkte
    210
    Beiträge
    41
    • 17. April 2006 um 00:40
    • #18

    Verwend java.math.BigDecimal zum exakten Rechnen mit arbitrary-precision Dezimalzahlen in Java.

  • Trux
    12
    Trux
    Mitglied
    Reaktionen
    26
    Punkte
    1.396
    Beiträge
    274
    • 17. April 2006 um 01:20
    • #19
    Zitat von Spockman

    Verwend java.math.BigDecimal zum exakten Rechnen mit arbitrary-precision Dezimalzahlen in Java.


    ist es das was du gemeint hast?

    PHP
    import java.math.*;
    
    
    public class Test{
    
        public static void main(String args[]){
    
            double d1 = 3.2;
            double d2 = 2.5;
            System.out.println(d1-d2);
    
            BigDecimal b1 = new BigDecimal(3.2);
            BigDecimal b2 = new BigDecimal(2.5);
            System.out.println(b1.subtract(b2));
    
            double result = b1.subtract(b2).doubleValue();
            System.out.println(result);
        }
    }
    Alles anzeigen
    PHP
    Trux@NOTEBOOK~
    $ java Test
    0.7000000000000002
    0.70000000000000017763568394002504646778106689453125
    0.7000000000000002
  • Spockman
    5
    Spockman
    Mitglied
    Punkte
    210
    Beiträge
    41
    • 17. April 2006 um 02:55
    • #20
    Zitat von Trux

    ist es das was du gemeint hast?

    Nein.

    Java
    import java.math.BigDecimal;
    
    
    public class Test{
        public static void main(String[]){
            BigDecimal b1 = new BigDecimal("3.2");
            BigDecimal b2 = new BigDecimal("2.5");
            System.out.println(b1.subtract(b2));
        }
    }


    $ java Test
    0.7

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!

Benutzerkonto erstellen Anmelden

Benutzer online in diesem Thema

  • 1 Besucher

Rechtliches

Impressum

Datenschutzerklärung