Kommata im Float?

  • Original von uschu.do
    eine andere Lösung könnte auch so aussehen:

    im String alle ',' durch '.' ersetzen - immer!
    Dann kann man ihn mit "floatValue" in eine Fliesskommazahl wandeln.

    Allerdings EUR- und Ct-Beträge nicht mit float oder double rechen! Die Fehler durch das Runden sind nicht zu vernachlässigen.

    Lieber mit NSDecimalNumber und + (NSDecimalNumber *)decimalNumberWithString:(NSString *)numericString diesen String weiter verarbeiten. Zum rechenen mit "Decimalen" gibt es NSDecimalMultiply, NSDecimalAdd usw.



    ich glaube das mit dem NSDecimal schaue ich mir mal näher an, das klingt nach der besten Lösung
  • Original von BlackBerryUser
    Original von mattik
    Original von BlackBerryUser
    ich frag doch nicht, wenns so einfach wäre. :P

    Gib' mal im Suchfeld (das auf der Portalseite, wo "erst suchen dann fragen" steht) die Wörter "Komma Punkt" ein. Dann bekommst Du als Ergebnis u.a. diesen Thread, in dem die Komma-statt-Punkt-Problematik beschrieben und gelöst wird.


    Das Script, dass Du dort angeboten hast ist aber die andere Richtung.

    float zu String.

    Ich will doch vom String zum float.

    Ich würde vorschlagen, Du probierst mal das aus was wir hier geschrieben haben (decimal, mzw. locale)
  • mit NSDecimal kam ich doch nicht so klar, wie ich dachte.

    Ich denke ich versuche jetzt doch mal Lucas Lösung: nur in cent zu rechnen.



    d.h.:

    ich muss den String umwandeln in ein INT?
    z.B. 77,50 in 7750 ich rechne dann ganz normal damit, und vor der Ausgabe teile ich einfach durch 100 und habe, dann wieder Euro und der Restwert sind die Cent?

    a) wie wandle ich die 77,50 von NSString in einen int ohne das Komma um?

    b) wie speichere ich das int später wieder als String mit , ? int / 100 -> vorderteil des Strings + "," + rest der division int/100 -> Nachkommastelle. oder?
  • ja hallo was ist denn hier los?

    die frage war wie er von 1234,56 einen float bekommt.
    Ich habe geantwortet mit NSNumberFormater. Das ist auch der wohl einzig richtige weg. Dort einfach numberFromString verwenden. Natürlich zuerst locale richtig setzen und wenn man ein NSDecimal haben will anstelle von NSNumber dann stellt man das eben im formatter ein.

    kleinste einheit verwenden ist ein totaler schmarrn:

    1 blatt papier kostet 0,001 Euro. Das wären dann 0 cent wenn mans auf den cent "runden" würde.
    ebenfalls macht es keinen sinn wenn man Tonnen (oder mehr) als gramm speichert. Es gibt ja auch fälle wo man genauere werte hat als gramm oder in dem fall cent. Also bitte ordentlich mahcen und nicht rundpfuschen!
  • Bei Währungsrechnungen rechnet man in int von Cent. Es kommt dabei nicht auf die Auflösung an, da Rundungen akzeptiert sind, sondern auf die Vermeidung von unbestimmten Verhalten. Mach mal 3.0 x 1.6 mit einem Float
    Es hat noch nie etwas gefunzt. To tear down the Wall would be a Werror!
    25.06.2016: [Swift] gehört zu meinen *Favorite Tags* auf SO. In welcher Bedeutung von "favorite"?
  • Original von gritsch
    kleinste einheit verwenden ist ein totaler schmarrn:

    1 blatt papier kostet 0,001 Euro. Das wären dann 0 cent wenn mans auf den cent "runden" würde.
    ebenfalls macht es keinen sinn wenn man Tonnen (oder mehr) als gramm speichert. Es gibt ja auch fälle wo man genauere werte hat als gramm oder in dem fall cent. Also bitte ordentlich mahcen und nicht rundpfuschen!

    Woher bekommst du bitte 1 Blatt Papier?
    Eher kosten 500 Blatt 0,50 Euro, also 50 Cent.
    (Bei dem Anbieter kaufe ich auch! Wer ist es?)
    Die Frage ist halt, was sinnvoll ist.
    Tonnen in Gramm umrechnen ist Blödsinn, wenn die kleinste benötigte Einheit Kilogramm ist.

    Das FLOAT und DOUBLE Rundungsfehler machen können ist ja wohl jedem klar.
    Je nachdem, was verlangt ist, ist die Umwandlung in INT sogar sinnvoll.

    a) int i = (int)([theString floatValue] * 100); // Alternativ * 100 für Zehntel Cent/ 3 Nachkommastellen
    b) zum Beispiel. Oder auch [NSString stringWithFormat:@"%d,%2d", (int)(i/100), (i%10)];

    Was will NSDecimal denn nicht tun?
    «Applejack» "Don't you use your fancy mathematics to muddle the issue!"

    Iä-86! Iä-64! Awavauatsh fthagn!

    kmr schrieb:

    Ach, Du bist auch so ein leichtgläubiger Zeitgenosse, der alles glaubt, was irgendwelche Typen vor sich hin brabbeln. :-P
  • Original von Tom9811
    Bei Währungsrechnungen rechnet man in int von Cent. Es kommt dabei nicht auf die Auflösung an, da Rundungen akzeptiert sind, sondern auf die Vermeidung von unbestimmten Verhalten. Mach mal 3.0 x 1.6 mit einem Float


    ne - siehe mein beispiel!

    wenn man mengen und stückpreise angibt kann es leicht vorkommen dass 1 stück zb 0,00012 Euro kostet. Dann bist du mit cents aufgeschmissen
  • Ich bin nicht aufgeschmissen. Wenn das Stück weniger als einen Cent kostet, wird es in dieser Menge nicht verkauft.

    Es geht darum, dass du bei einfacher Zinsrechnung absolut bereit bist zu akzeptieren, dass 100,02 € x 10 % nicht aufgeht. Da hat sich noch nie ein Bankkunde beschwert. Wenn da aber auf einmal ein Bruchteil aus dem nichts auftaucht, wechselst du deine Bank. Sofort.
    Es hat noch nie etwas gefunzt. To tear down the Wall would be a Werror!
    25.06.2016: [Swift] gehört zu meinen *Favorite Tags* auf SO. In welcher Bedeutung von "favorite"?
  • NSDecimalNumber rundet "sauber" (aka dezimal). Das ist schon deutlich besser:
    10
    NSDecimalNumber
    Ich hatte Sie bereits davor gewarnt, float und double für exakte Berechnungen etwa
    in finanzmathematischen Anwendungen zu verwenden. Um NSDecimalNumber
    einen Sinn zu geben, will ich das ausführen:
    Grundsätzlich speichert ein Computer einen Wert in einer Speichereinheit fester
    Größe. Die konkrete Größe wird von dem Datentypen festgelegt, also etwa double.
    In diesem Speicher ist nur eine bestimmte Anzahl von Kombinationen darstellbar. Es
    können Millionen sein, aber eben nur eine bestimmte Anzahl. Demgegenüber exis-
    tieren unendlich viele Dezimalbrüche. Daher kann ein Computer gar nicht alle dar-
    stellen und muss zu Rundungen greifen. Von irrationalen Zahlen wollen wir hier
    noch gar nicht sprechen.
    Sie können sich das im Wesentlichen wie bei Ihrem Taschenrechner vorstellen, der
    nur eine bestimmte Anzahl von Stellen anzeigt. Man nennt dies die »Mantisse«. Dies
    ist dementsprechend bei Werten, die sich mit 8 Stellen ausdrücken lassen, auch un-
    problematisch. Hat die Zahl allerdings mehr Stellen, so lässt sie sich nicht mehr im
    Computer speichern. Die überzähligen Stellen werden daher rechts abgeschnitten,
    der Wert entspricht nicht mehr der ursprünglichen Zahl. Die Länge der Mantisse gibt
    also die maximale Genauigkeit an Stellen wieder. Das ist zu akzeptieren.
    Jetzt kommt aber hinzu, dass der Computer nicht mit 10 Ziffern 0 bis 9 (Dezimalsystem)
    rechnet, sondern mit 2 Ziffern 0 und 1 (Binärsystem). Man kann sich das vereinfacht
    so vorstellen, dass die Stellen hinter dem Komma nicht die Werte Zehntel, Hunderts-
    tel usw. haben, sondern Halb, Viertel usw. Zwar lässt sich das problemlos umwandeln.
    Aber beim Abschneiden der Zahlen entstehen dann nicht mehr »glatte« Dezimalbrü-
    che, sondern »glatte« Binärbrüche. Und das sieht dann doch zuweilen seltsam aus, weil
    dies in einen Dezimalbruch zurückgewandelt etwas völlig Krummes ergeben kann.
    Aus diesem Grunde existiert eine Klasse NSDecimalNumber, die Dezimalbrüche
    wirklich als Dezimalzahlen speichert. Wenn diese also an die Grenzen ihrer Genau-
    kapitel 4
    container
    igkeit kommen, so werden »wenigstens« für uns Menschen glatte Rundungen vor-
    genommen.
    AUFGEPASST
    Übrigens lassen sich Zahlen darstellen, die mehr Stellen besitzen, als gespeichert
    werden. Man bedient sich dann sogenannter Exponenten, wie Sie es vom Taschen-
    rechner kennen, wenn er etwa »E-14« anzeigt. So hat NSDezimalNumber etwa eine
    Genauigkeit von 38 Stellen. Eine Zahl, die 40 Stellen vor dem Komma hat, wird
    dann mit ihren ersten 38 Stellen gespeichert, wobei die letzten beiden Stellen vor
    dem Komma 0 sind: Aus 3.756.675.[…].516.318 wird also 3.756.675.[…].516.300.
    Addiere ich auf eine solche Zahl zum Beispiel 0.000.000.[…].000.04, so ändert sie
    ihren Wert nicht!
    Es hat noch nie etwas gefunzt. To tear down the Wall would be a Werror!
    25.06.2016: [Swift] gehört zu meinen *Favorite Tags* auf SO. In welcher Bedeutung von "favorite"?
  • Original von Tom9811
    Es geht darum, dass du bei einfacher Zinsrechnung absolut bereit bist zu akzeptieren, dass 100,02 € x 10 % nicht aufgeht.

    Nun, unsere Warenwirtschaftssoftware leistet sich einen gewaltigen Schnitzer:
    Auftragsbestätigungen und Rechnungen unterscheiden sich. Die Rechnungen sind alle mathematisch korrekt.
    Die Auftragsbestätigungen weichen um bis zu 15% von den Rechnungen ab, wenn Rabatte ins Spiel kommen!

    Es wurde eingeräumt, dass das Formular für die Auftragsbestätigung 'falsch rundet'...
    Mit Ganzzahlen wäre das nicht passiert. Bzw. ist es nicht passiert. Das Rechnungsformular rechnet schließlich richtig.
    «Applejack» "Don't you use your fancy mathematics to muddle the issue!"

    Iä-86! Iä-64! Awavauatsh fthagn!

    kmr schrieb:

    Ach, Du bist auch so ein leichtgläubiger Zeitgenosse, der alles glaubt, was irgendwelche Typen vor sich hin brabbeln. :-P
  • Original von Tom9811
    NSDecimalNumber rundet "sauber" (aka dezimal). Das ist schon deutlich besser:
    10
    NSDecimalNumber
    Ich hatte Sie bereits davor gewarnt, float und double für exakte Berechnungen etwa
    in finanzmathematischen Anwendungen zu verwenden. Um NSDecimalNumber
    einen Sinn zu geben, will ich das ausführen:
    Grundsätzlich speichert ein Computer einen Wert in einer Speichereinheit fester
    Größe. Die konkrete Größe wird von dem Datentypen festgelegt, also etwa double.
    In diesem Speicher ist nur eine bestimmte Anzahl von Kombinationen darstellbar. Es
    können Millionen sein, aber eben nur eine bestimmte Anzahl. Demgegenüber exis-
    tieren unendlich viele Dezimalbrüche. Daher kann ein Computer gar nicht alle dar-
    stellen und muss zu Rundungen greifen. Von irrationalen Zahlen wollen wir hier
    noch gar nicht sprechen.
    Sie können sich das im Wesentlichen wie bei Ihrem Taschenrechner vorstellen, der
    nur eine bestimmte Anzahl von Stellen anzeigt. Man nennt dies die »Mantisse«. Dies
    ist dementsprechend bei Werten, die sich mit 8 Stellen ausdrücken lassen, auch un-
    problematisch. Hat die Zahl allerdings mehr Stellen, so lässt sie sich nicht mehr im
    Computer speichern. Die überzähligen Stellen werden daher rechts abgeschnitten,
    der Wert entspricht nicht mehr der ursprünglichen Zahl. Die Länge der Mantisse gibt
    also die maximale Genauigkeit an Stellen wieder. Das ist zu akzeptieren.
    Jetzt kommt aber hinzu, dass der Computer nicht mit 10 Ziffern 0 bis 9 (Dezimalsystem)
    rechnet, sondern mit 2 Ziffern 0 und 1 (Binärsystem). Man kann sich das vereinfacht
    so vorstellen, dass die Stellen hinter dem Komma nicht die Werte Zehntel, Hunderts-
    tel usw. haben, sondern Halb, Viertel usw. Zwar lässt sich das problemlos umwandeln.
    Aber beim Abschneiden der Zahlen entstehen dann nicht mehr »glatte« Dezimalbrü-
    che, sondern »glatte« Binärbrüche. Und das sieht dann doch zuweilen seltsam aus, weil
    dies in einen Dezimalbruch zurückgewandelt etwas völlig Krummes ergeben kann.
    Aus diesem Grunde existiert eine Klasse NSDecimalNumber, die Dezimalbrüche
    wirklich als Dezimalzahlen speichert. Wenn diese also an die Grenzen ihrer Genau-
    kapitel 4
    container
    igkeit kommen, so werden »wenigstens« für uns Menschen glatte Rundungen vor-
    genommen.
    AUFGEPASST
    Übrigens lassen sich Zahlen darstellen, die mehr Stellen besitzen, als gespeichert
    werden. Man bedient sich dann sogenannter Exponenten, wie Sie es vom Taschen-
    rechner kennen, wenn er etwa »E-14« anzeigt. So hat NSDezimalNumber etwa eine
    Genauigkeit von 38 Stellen. Eine Zahl, die 40 Stellen vor dem Komma hat, wird
    dann mit ihren ersten 38 Stellen gespeichert, wobei die letzten beiden Stellen vor
    dem Komma 0 sind: Aus 3.756.675.[…].516.318 wird also 3.756.675.[…].516.300.
    Addiere ich auf eine solche Zahl zum Beispiel 0.000.000.[…].000.04, so ändert sie
    ihren Wert nicht!


    sag ich ja. Hab nur gesagt dass int der falsche weg ist.
  • also, wenn ich weiss, dass meine Strings immer im Format '#0,00' sind (Immer genau 2 Nachkommastellen und niemals mehr), dann kann ich ohne kompizierte Umrechnung auf Cents kommen.

    Ich entferne in meinem Euro-String das Komma und schon habe ich Cents. Diese kann ich dann ohne weitere Rechnung als "int" convertieren.

    Tausender-Trennzeichen muss ich auch durch "nichts" erstetzen und schon klappts mit dem Interger.
    Wenn Du immer nur das tust was du schon kannst - wirst du immer das bleiben, was du heute bist.
  • Original von uschu.do
    also, wenn ich weiss, dass meine Strings immer im Format '#0,00' sind (Immer genau 2 Nachkommastellen und niemals mehr), dann kann ich ohne kompizierte Umrechnung auf Cents kommen.

    Ich entferne in meinem Euro-String das Komma und schon habe ich Cents. Diese kann ich dann ohne weitere Rechnung als "int" convertieren.

    Tausender-Trennzeichen muss ich auch durch "nichts" erstetzen und schon klappts mit dem Interger.


    du musst dann alle punkte entferen. dann musst du das , durch punkt ersetzen, dann den floatValue holen und mit 100 multiplizeiren und in einen int packen. NSNumberFormatter leifert dir gleich eine NSDecimal.
  • wenn mein NSString preis = @"1.234,56"; dann kann ich

    Quellcode

    1. NSArray * preisComps = [preis componentsSeparatedByString:@".,"];
    2. NSString * preisString = [preisComps componentsJoinedByString:@""];
    3. int preisCent = [preisString intValue];


    Das funzt auch mit @"1,234.56".

    Warum komplizierter als nötig?
    Wenn Du immer nur das tust was du schon kannst - wirst du immer das bleiben, was du heute bist.
  • naja, das ist ja kompletter pfusch weil ihr annehmt dass das format XXX.XX ist. ändert sich das mal dass zum beispiel auch 123,4 oder 123,456 kommen kann dann ist eure geschichte wieder falsch. Außerdem habt ihr hier rießen overhead. mit arrays etc... Man sollte so programmieren dass es auch wiederverwendbar ist
  • klar - die voraussetzung ist, dass das Format immer 2 Nachkommastellen hat. Zur Not kann man es auch mit rel. einfachen Stringoperationen passend machen.

    Zum Beispiel checken, ob das letzte Element im Array die Länge 2 hat, wenn nicht, hängt man eine '0' dran.
    Wenn Du immer nur das tust was du schon kannst - wirst du immer das bleiben, was du heute bist.
  • Original von uschu.do
    klar - die voraussetzung ist, dass das Format immer 2 Nachkommastellen hat. Zur Not kann man es auch mit rel. einfachen Stringoperationen passend machen.

    Zum Beispiel checken, ob das letzte Element im Array die Länge 2 hat, wenn nicht, hängt man eine '0' dran.


    und warum bitte solche riesen umstände machen dass es dann ein EINIGEN fällen funktioniert und nicht was vorgefertigtes verwenden das in allen fällen funktioniert...
    naja, macht was ihr woll (ich würd euch halt nicht beschäftigen... ;-))
  • Original von uschu.do
    also, wenn ich weiss, dass meine Strings immer im Format '#0,00' sind (Immer genau 2 Nachkommastellen und niemals mehr), dann kann ich ohne kompizierte Umrechnung auf Cents kommen.

    Ich entferne in meinem Euro-String das Komma und schon habe ich Cents. Diese kann ich dann ohne weitere Rechnung als "int" convertieren.

    Tausender-Trennzeichen muss ich auch durch "nichts" erstetzen und schon klappts mit dem Interger.

    Hier kann ich gritsch nur zustimmen:Wieso willst du etwas eigenes bauen,was auch noch zweifelhaft ist? Vllt bin ich hier missverstanden worden: Das einmalige verwenden eines Floats ist unschädlich. Das kann auch zwischendurch bei Zinsrechnung notwendig sein. Ein Float macht aus 4.8 eben mal gerne 4.800000000000000312, aber nicht 5.378029.

    Man darf nur mit den Floats nicht "durchrechnen",weil sich dann die Fehler addieren.Das also nach dem vorgesehenem Weg zunächst in einen Float zu wandeln und dann in ein Int-Format zu bringen, dürfte völlig ungefährlich sein.

    Und in der Tat sind die von gritsch genannten Klassen exakt dazu da, wozu er sie verwendet.
    Es hat noch nie etwas gefunzt. To tear down the Wall would be a Werror!
    25.06.2016: [Swift] gehört zu meinen *Favorite Tags* auf SO. In welcher Bedeutung von "favorite"?