Seite 1 von 3 123 LetzteLetzte
Ergebnis 1 bis 15 von 43
  1. #1
    Avatar von mikdoe
    mikdoe ist offline Administrator
    registriert
    01-05-2010
    Beiträge
    7.706

    Fließkomma- und Ganzzahlen in JavaScript

    Dieser Thread ist ein Extrakt aus Thread http://forum.jswelt.de/javascript/57...ig-runden.html (Richtig runden.)

    Ich mache solche Rechnung bewußt niemals in JS, weil ich auf den Browser und seine Rechnerei keinen Einfluss habe. Daher ist mein Mathematik-JS extrem beschränkt.
    Aber wenn ich müsste würde ich wohl mit soetwas wie z.B. Math.floor() die Ganzzahl eines Wertes ziehen und danach den Dezimalpunkt in der Zahl suchen mit soetwas wie indexOf() und abhängig von der dritten Stelle nach dem Dezimalpunkt (bei >4 soweit überhaupt vorhanden) zu meiner Ganzzahl eine addieren.
    Und ab diesem Punkt würde ich intern nur noch mit dieser Ganzzahl weiter rechnen und erst bei der Ausgabe (so spät wie möglich) wieder durch 100 dividieren zwecks Anzeige.
    Dein Beispiel 24,37 ist übrigens ungeeignet da es nicht gerundet werden muss. 24,375 als Ergebnis einer Rechnung wäre das bessere Beispiel. Da müsste dann 2438 als Ganzzahl rauskommen.

    Aber eine Warnung noch: Das garantiert auch nicht in allen Fällen den Erfolg! Auch bei der Umwandung in eine Ganzzahl können Fehler passieren. Selbst die Ur-Serversprachen wie z.B. Perl kommt bei solchen Aktionen (wg. fehlendem internen Typecast) manchmal an ihre Grenzen.
    Wenn es hier also um was geht, mach das weder mit JS noch mit Perl sondern in Sprachen die rechnen können, wie z.B. die C-Dialekte (hab ich mir sagen lassen).
    Geändert von mikdoe (05-06-2013 um 08:36 Uhr)

  2. #2
    ein schlauer ist offline Lounge-Member
    registriert
    18-08-2004
    Beiträge
    14.671

    AW: Richtig runden.

    Zitat Zitat von mikdoe Beitrag anzeigen
    Ich mache solche Rechnung bewußt niemals in JS, weil ich auf den Browser und seine Rechnerei keinen Einfluss habe. Daher ist mein Mathematik-JS extrem beschränkt.
    Aber wenn ich müsste würde ich wohl mit soetwas wie z.B. Math.floor() die Ganzzahl eines Wertes ziehen und danach den Dezimalpunkt in der Zahl suchen mit soetwas wie indexOf() und abhängig von der dritten Stelle nach dem Dezimalpunkt (bei >4 soweit überhaupt vorhanden) zu meiner Ganzzahl eine addieren.
    Warum so ein Geschwurbel?
    Das macht doch keinen Sinn.
    Zitat Zitat von mikdoe Beitrag anzeigen
    Und ab diesem Punkt würde ich intern nur noch mit dieser Ganzzahl weiter rechnen und erst bei der Ausgabe (so spät wie möglich) wieder durch 100 dividieren zwecks Anzeige.
    Dein Beispiel 24,37 ist übrigens ungeeignet da es nicht gerunden werden muss. 24,375 als Ergebnis einer Rechnung wäre das bessere Beispiel. Da müsste dann 2438 als Ganzzahl rauskommen.
    Das Problem bei seinem Beispiel ist es, dass er diese Menge aufteilen will, in 77% und zweimal 11,5%. Mathematisch geht das ohne Probleme. Das Problem ist, dass es Geld nur in Cent gibt.

  3. #3
    Avatar von mikdoe
    mikdoe ist offline Administrator
    registriert
    01-05-2010
    Beiträge
    7.706

    AW: Richtig runden.

    Zitat Zitat von ein schlauer Beitrag anzeigen
    Warum so ein Geschwurbel?
    Das macht doch keinen Sinn.
    Vielleicht hier nicht unbedingt. Aber generell schon. Ich beschäftige mich schon länger mit diesem Thema - zwar nicht in JS - aber da kann man lustige Dinge erleben.

    Zitat Zitat von ein schlauer Beitrag anzeigen
    Das Problem bei seinem Beispiel ist es, dass er diese Menge aufteilen will, in 77% und zweimal 11,5%. Mathematisch geht das ohne Probleme. Das Problem ist, dass es Geld nur in Cent gibt.
    OK, aber wenn schon beim Runden nicht richtig gerechnet wird, wird es am Ende nie stimmen.

  4. #4
    ein schlauer ist offline Lounge-Member
    registriert
    18-08-2004
    Beiträge
    14.671

    AW: Richtig runden.

    Zitat Zitat von mikdoe Beitrag anzeigen
    Ja, die Richtung von kkapsner schwebte mir auch vor.
    Sieht auch meiner Perl Funktion ähnlich, die ich benutze.
    Warum?
    Und was bedeutet das Ergebnis dieser Funktion? Bei mir zeigt sie 280, 280, 1877 an.

  5. #5
    Avatar von mikdoe
    mikdoe ist offline Administrator
    registriert
    01-05-2010
    Beiträge
    7.706

    AW: Richtig runden.

    Zitat Zitat von ein schlauer Beitrag anzeigen
    Warum?
    Weil es in Perl aufgrund des fehlenden Typecast diverse Probleme sowohl beim int()'en als auch beim Rechnen und Darstellen gibt.
    Wie das genau in JS ist weiß ich nicht, habe ich nicht untersucht.
    Auf jeden Fall tun es in Perl einfache Lösungen nicht.
    Und der Ansatz von Korbinian kam mir einfach nur bekannt vor.

  6. #6
    ein schlauer ist offline Lounge-Member
    registriert
    18-08-2004
    Beiträge
    14.671

    AW: Richtig runden.

    Zitat Zitat von mikdoe Beitrag anzeigen
    Und der Ansatz von Korbinian kam mir einfach nur bekannt vor.
    Dann müßtest du mir doch erklären können, was er darstellt?

    wieso fehlt in Perl der typecast? Im gegenteil, in Perl wird ähnlich umgewandelt wie in JS.

  7. #7
    Avatar von mikdoe
    mikdoe ist offline Administrator
    registriert
    01-05-2010
    Beiträge
    7.706

    AW: Richtig runden.

    Zitat Zitat von ein schlauer Beitrag anzeigen
    Dann müßtest du mir doch erklären können, was er darstellt?
    Ich sehe nur Regexe und Stringverarbeitung. Hab es nicht tiefergehend analysiert.

    Zitat Zitat von ein schlauer Beitrag anzeigen
    wieso fehlt in Perl der typecast? Im gegenteil, in Perl wird ähnlich umgewandelt wie in JS.
    Ja?
    Warum bringt dieses Script denn zwar 57 aber "nein" als Ergebnis?
    Code:
    #!/usr/bin/perl
    use strict;
    use warnings;
    my $a = .57*100;
    print "57 == $a? ".($a==57?'ja':'nein')."\n";

  8. #8
    tsseh ist offline Foren-Gott
    registriert
    19-05-2008
    Beiträge
    5.666

    AW: Richtig runden.

    was wird denn das für eine lustige diskussion?

    Zitat Zitat von mikdoe Beitrag anzeigen
    Ich sehe nur Regexe und Stringverarbeitung.
    hab ich auch schon mal gesehen


    Zitat Zitat von mikdoe Beitrag anzeigen
    Warum bringt dieses Script denn zwar 57 aber "nein" als Ergebnis?
    weil .57 binär nicht darstellbar ist (jedenfalls nicht mit den zur verfügung stehenden bits, ob überhaupt will ich jetzt nicht ausrechnen)
    aber gerundet - und darum geht es ja - stimmt alles

    Code:
    var a = (.57*100).toFixed(0);
      alert("" + ("57" == a) + " " + a);

  9. #9
    Avatar von mikdoe
    mikdoe ist offline Administrator
    registriert
    01-05-2010
    Beiträge
    7.706

    AW: Richtig runden.

    Zitat Zitat von hesst Beitrag anzeigen
    was wird denn das für eine lustige diskussion?
    Um es mit Rudi zu singen, "ein bisschen Spaß muss sein...."

    Zitat Zitat von hesst Beitrag anzeigen
    aber gerundet - und darum geht es ja - stimmt alles
    Und wie sähe das in Perl aus?

  10. #10
    tsseh ist offline Foren-Gott
    registriert
    19-05-2008
    Beiträge
    5.666

    AW: Richtig runden.

    Zitat Zitat von mikdoe Beitrag anzeigen
    Und wie sähe das in Perl aus?
    irgendwas mit vielen sonderzeichen.

  11. #11
    ein schlauer ist offline Lounge-Member
    registriert
    18-08-2004
    Beiträge
    14.671

    AW: Richtig runden.

    Zitat Zitat von mikdoe Beitrag anzeigen
    Und wie sähe das in Perl aus?
    z.b. so:
    PHP-Code:
    #!/usr/bin/perl -w
    use strict;
    my $a sprintf '%0.0f'.57*100;
    print 
    "57 == $a? ".($a==57?'ja':'nein')."\n"

  12. #12
    ein schlauer ist offline Lounge-Member
    registriert
    18-08-2004
    Beiträge
    14.671

    AW: Richtig runden.

    Zitat Zitat von mikdoe Beitrag anzeigen
    Ich sehe nur Regexe und Stringverarbeitung. Hab es nicht tiefergehend analysiert.
    Ich dachte es käme dir bekannt vor?

  13. #13
    Avatar von kkapsner
    kkapsner ist offline Super Moderator
    registriert
    28-03-2008
    Beiträge
    17.695

    AW: Richtig runden.

    Zitat Zitat von ein schlauer Beitrag anzeigen
    Warum sollten das drei Stellen nach dem Komma sein wenn du nur zwei angibst? Es sollte 4.93 sein und ist es auch.
    - 'tschuldigung. Hatte mich vertippt. Meinte natürlich 4.93 - aber deine Funktion spuckt 4.94 aus.
    Zitat Zitat von ein schlauer Beitrag anzeigen
    Das Problem ist, die Länge der Zahl. Soviele Stellen kannst du mit JS nicht darstellen. alert(4.9349999999999999); rundet bereits auf 4.935 was aber auch richtig ist.
    Natürlich kann JS soviele Stellen darstellen Number.MIN_VALUE ist 5e-324 (und z.B. 1st 1.0000000000000001 !== 1.0000000000000002). Es ist nur an der Grenze und wird intern genauso gespeichert wie 4.935 - zu welcher Zahl jetzt "richtig" gerundet werden soll, ist jetzt fraglich.
    Auch "rundet" alert(4.9349999999999999.toFixed(16)) nicht mehr zu 4.9350...

    Um das Ganze auf einen Punkt zu bringen: JS hat ein Zahlenformat, das Dezimalzahlen mit Fließkommaanteil nicht immer korrekt repräsentieren kann. Das kann schnell zu unerwartetem Verhalten führen (ich denke mal das Bekannteste ist 0.1 + 0.1 + 0.1 !== 0.3). ABER Ganzzahlen können 100%ig korrekt gespeichert werden (wenn sie zwischen -2^31 und 2^31-1 - also -2147483648 und 2147483647). Also wenn es um Geld geht immer in Ganzzahlen arbeiten (außer man hat Geldbeträge über 2.1 Milliarden - aber dann sollte man sowieso nicht mit JS arbeiten...).

    Die Funktion war einfach nur an die Originalfrage angelehnt - dort wurde Geld nach einem bestimmten Prozentanteil verteil. Das habe ich nachgebildet (ist das Beispiel mit den 11.5%).
    Geändert von mikdoe (05-06-2013 um 09:12 Uhr) Grund: Teilweise verschoben

  14. #14
    Avatar von mikdoe
    mikdoe ist offline Administrator
    registriert
    01-05-2010
    Beiträge
    7.706

    AW: Richtig runden.

    Zitat Zitat von ein schlauer Beitrag anzeigen
    z.b. so:
    Code:
    sprintf '%0.0f', .57*100
    Ja, meine Frage war retorisch. Das Beispiel sollte zeigen, dass man eine scheinbar einfache Sache noch extra behandeln muss.
    Soviel zum Thema "immer mit Ganzzahlen arbeiten". Selbst bei einer einfachen Multiplikation muss man damit rechnen, dass die Programmiersprache intern anders speichert als man aufgrund der print Ausgabe glaubt.
    Das meinte ich mit den Überraschungen, die man hier und da erlebt
    Daher: Auch das Arbeiten mit Ganzzahlen ist kein Allheilmittel.
    Ich weiß allerdings nicht, ob es diese Fallgrube auch in JS gibt. Würde mich mal interessieren, ob da jemand mehr zu weiß.

    Zitat Zitat von ein schlauer Beitrag anzeigen
    Ich dachte es käme dir bekannt vor?
    Grob, ja. Nicht im Detail.

    Zitat Zitat von kkapsner Beitrag anzeigen
    ABER Ganzzahlen können 100%ig korrekt gespeichert werden (wenn sie zwischen -2^31 und 2^31-1 - also -2147483648 und 2147483647).
    Davon geht man bei Perl wahrscheinlich auch aus, ist aber nicht so, wie das Beispiel beweist.
    Würdest du für diese Aussage deine Beine ins Feuer legen, Korbinian?

  15. #15
    tsseh ist offline Foren-Gott
    registriert
    19-05-2008
    Beiträge
    5.666

    AW: Richtig runden.

    Zitat Zitat von kkapsner Beitrag anzeigen
    - 'tschuldigung. Hatte mich vertippt. Meinte natürlich 4.93 - aber deine Funktion spuckt 4.94 aus.
    Natürlich kann JS soviele Stellen darstellen Number.MIN_VALUE ist 5e-324 (und z.B. 1st 1.0000000000000001 !== 1.0000000000000002). Es ist nur an der Grenze und wird intern genauso gespeichert wie 4.935 - zu welcher Zahl jetzt "richtig" gerundet werden soll, ist jetzt fraglich.
    Auch "rundet" alert(4.9349999999999999.toFixed(16)) nicht mehr zu 4.9350...

    JS hat ein Zahlenformat, das Dezimalzahlen mit Fließkommaanteil nicht immer korrekt repräsentieren kann.
    Das hat aber nichts mit JS zu tun. das ist so definiert in allen Sprachen! http://de.wikipedia.org/wiki/IEEE_754
    Ich wüsste jetzt auch keine Sprache, die von Hause aus mehr als 64-Bit Gleitkommazahlen anbietet.

    Zitat Zitat von kkapsner Beitrag anzeigen
    Das kann schnell zu unerwartetem Verhalten führen
    eigentlich nicht. 1/3, 2/55, ... kannst du auch im dezimalen nicht als Gleitkommazahlen darstellen. und jeder der mehr als Briefe am rechner schreibt sollte eigentlich wissen wie gleitkommazahlen binär dargestellt werden und sich nicht wundern, daß +0 != -0 ist.

    EDIT: hier kann man sich schön die darstellung als 32-Bit/64-Bit/... Gleitkommazahl im Speicher ansehen.
    Geändert von mikdoe (05-06-2013 um 09:08 Uhr) Grund: Quote repariert und verschoben

Seite 1 von 3 123 LetzteLetzte

Ähnliche Themen

  1. Antworten: 9
    Letzter Beitrag: 09-10-2013, 11:52
  2. Antworten: 4
    Letzter Beitrag: 19-12-2012, 23:06
  3. Antworten: 3
    Letzter Beitrag: 19-10-2011, 08:18
  4. Antworten: 0
    Letzter Beitrag: 07-08-2011, 10:28
  5. Math.round Problem mit rundung bei Ganzzahlen
    Von siggedy im Forum JavaScript
    Antworten: 2
    Letzter Beitrag: 01-12-2010, 01:14

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •