Arbeiten mit Dezimalzahlen

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • Arbeiten mit Dezimalzahlen

    Hallo,

    ich arbeite an einer iOS-App (Swift) bei der Anwender verschiedene Werte eingeben muss die validiert werden und einen Wert für gültig oder ungültig erklären. Jetzt stoße ich auf das Problem mit Fließkommazahlen, dass ein angegebener Wert von 0.3 als 0.2999999999 behandelt wird und somit kleiner statt gleich dem Grenzwert von 0.3 ist und somit irrtümlicherweise ungültig ist. Nachdem ich etwas recherchiert habe und von Double auf NSDecimalNumber und Decimal umgestiegen bin tauchen trotzdem ähnliche Probleme auf. Wie gehe ich richtig damit um? Falls relevant: Ich brauche keine 10 Stellen Genauigkeit nach dem Komme. 5 Nachkommastellen würden reichen.

    Gruß
  • Was hindert Dich, Eingaben vorn der Validierung entsprechend der vorgegebenen Genauigkeit zu runden?

    Nur mal laut gedacht, Mattes

    Edit: Ich korrigiere mich selber :D Da dürfte Dir die internen Darstellung noch immer einen Strich durch die Rechung machen. Ich würde den Absolutwert der Differenz Eingabe vs. Limit gegen einen Toleranzbereich vergleichen.
    Diese Seite bleibt aus technischen Gründen unbedruckt.
  • Was hat denn das mit Krampf zu tun? Wenn Du dezimale genauigkeit bei Fließkomma haben willst, dann mach gefälligst aus den Fließkommazahlen Dezimals indem Du sie mit 10000 multiplizierst. Sorry aber das ist jetzt wirklich nicht kompliziert. Oder willst du am besten deine App Idee einfach Siri diktieren und die schreibt dann deinen Sourcecode?
    2 Stunden Try & Error erspart 10 Minuten Handbuchlesen.

    Pre-Kaffee-Posts sind mit Vorsicht zu geniessen :)
  • Thallius schrieb:

    Was hat denn das mit Krampf zu tun? Wenn Du dezimale genauigkeit bei Fließkomma haben willst, dann mach gefälligst aus den Fließkommazahlen Dezimals indem Du sie mit 10000 multiplizierst. Sorry aber das ist jetzt wirklich nicht kompliziert. Oder willst du am besten deine App Idee einfach Siri diktieren und die schreibt dann deinen Sourcecode?
    Bis heute keinen vernünftigen Kommentar von dir gesehen...

    Natürlich ist das nicht kompliziert. Aber weniger Krampf wäre es wenn es einen Typ (z.B. Decimal oder NSDecimalNumber) gäbe der einem sowas erspart.
  • adiminator schrieb:

    Thallius schrieb:

    Was hat denn das mit Krampf zu tun? Wenn Du dezimale genauigkeit bei Fließkomma haben willst, dann mach gefälligst aus den Fließkommazahlen Dezimals indem Du sie mit 10000 multiplizierst. Sorry aber das ist jetzt wirklich nicht kompliziert. Oder willst du am besten deine App Idee einfach Siri diktieren und die schreibt dann deinen Sourcecode?
    Bis heute keinen vernünftigen Kommentar von dir gesehen...
    Natürlich ist das nicht kompliziert. Aber weniger Krampf wäre es wenn es einen Typ (z.B. Decimal oder NSDecimalNumber) gäbe der einem sowas erspart.
    Gibts ja. Und einen passenden NSNumberFormatter dazu.
    Warum du die nicht verwenden wallst hast du aber nicht erklärt.
    Eine einfache Alternative habe ich ja genannt.
  • gritsch schrieb:

    Wahrscheinlich hast du sie einfach falsch verwendet - aber ohne konkreten Code und dazugehörige Fehler können wir wenig sagen.
    Hier einfach einpaar Beispielzeilen:

    Quellcode

    1. var a = Decimal(0.035) // 0.03500000000000000512
    2. a.multiply(by: Decimal(1000.0)) // 35.00000000000000512
    3. var b = NSDecimalNumber(value: 0.035) // 0.03500000000000002
    Jetzt mal unabhängig davon wie sinnvoll der Code ist.
  • adiminator schrieb:

    Quellcode

    1. var a = Decimal(0.035) // 0.03500000000000000512
    2. a.multiply(by: Decimal(1000.0)) // 35.00000000000000512
    3. var b = NSDecimalNumber(value: 0.035) // 0.03500000000000002

    Das ist ja 'nur' eine Frage der näherungsweisen Darstellung als Zeichenkette, nicht des tatsächlich gespeicherten Wertes.

    Vgl. z.B. basierend auf Deinem Code:

    Quellcode

    1. a == b as Decimal // true
    2. var d: Double = 0.035
    3. var e: Float = 0.035
    4. d == Double(e) // false WTF!!!
    5. print(d) // 0.035
    6. print(d.description) // 0.035
    7. print(d.debugDescription) // 0.035000000000000003 WTF
    8. print(e) // 0.035
    9. print(e.description) // 0.035
    10. print(e.debugDescription) // 0.0350000001
    Alles anzeigen
    Das iPhone sagt: "Zum Antworten streichen". Wie? Echt Jetzt? Muß ich erst die Wohnung streichen!?
  • adiminator schrieb:

    Sollte NSDecimalNumber nicht genau sowas lösen?
    Ich halte eine Umstellung auf dezimale Zahlen nicht unbedingt für sinnvoll, weil das Rechnen (sowohl in der Programmierung als auch in der Ausführung) damit in der Regel wesentlich aufwändiger wird. Der Gewinn, die angeblich höhere Genauigkeit stellt sich häufig auch als Chimäre heraus, und bei vielen Algorithmen (iterierte Verfahren), dürfte ziemlicher Müll herauskommen.

    Warum ist beispielsweise der exakte Grenzwert von 0.3 so wichtig oder geht auch beispielsweise 0.99995? Ich würde jedenfalls die verwendete Arithmetik nicht wegen eines Grenzwerts auswählen bzw. umstellen.
    „Meine Komplikation hatte eine Komplikation.“
  • gritsch schrieb:

    Wahrscheinlich hast du sie einfach falsch verwendet - aber ohne konkreten Code und dazugehörige Fehler können wir wenig sagen.
    Ein großes Wort gelassen ausgesprochen.

    adiminator schrieb:


    Hier einfach einpaar Beispielzeilen:

    Quellcode

    1. var a = Decimal(0.035) // 0.03500000000000000512
    2. a.multiply(by: Decimal(1000.0)) // 35.00000000000000512
    3. var b = NSDecimalNumber(value: 0.035) // 0.03500000000000002
    Jetzt mal unabhängig davon wie sinnvoll der Code ist.
    Ja, das ist ja auch kein Wunder. Wie kommt denn die 0.035 in die Decimal-Objekte rein? Richtig als Double. Und da denkt Decimal:

    Decimal schrieb:

    Was soll ich denn jetzt mit 0xec51b81e85eba13f machen? Ach ich wandle einfach mal so viele Stellen wie möglich um, wie ich das immer mache.
    Wenn du genau 0.035 als Decimal haben willst, solltest du Decimal(string: "0.035") probieren.
    „Meine Komplikation hatte eine Komplikation.“
  • macmoonshine schrieb:

    Ja, das ist ja auch kein Wunder. Wie kommt denn die 0.035 in die Decimal-Objekte rein? Richtig als Double. Und da denkt Decimal:

    Decimal schrieb:

    Was soll ich denn jetzt mit 0xec51b81e85eba13f machen? Ach ich wandle einfach mal so viele Stellen wie möglich um, wie ich das immer mache.
    Wenn du genau 0.035 als Decimal haben willst, solltest du Decimal(string: "0.035") probieren.
    Mal wieder ein lerreiches Beispiel für "garbage in, garbage out"...