Ich habe ein
float a = 1412.244019;
und ich muss auf die nächste zweite Dezimalstelle wie 1412.24000000 gerundet werden. Ich verstehe, dass, wenn ich ein mit nur zwei Dezimalstellen präsentieren möchte, ich% .2f verwende, aber das ist NICHT der Fall. Ich brauche das neue a aus mathematischen Gründen als Schwimmer.
Ich habe ein paar Methoden ausprobiert, die beim Stackoverflow ohne Glück gefunden wurden. Das offensichtliche, das ich benutzte, erwähne ich unten, aber hatte noch kein Glück, es zu benutzen. Kannst du sehen, warum die Magie nicht geschieht?
PS: Es bewirkt manchmal den gewünschten Effekt, NICHT immer, was mich zum Nachdenken bringt ... hmmm ...
Danke im Voraus.
Code:
float a = 1412.244019;
NSLog(@"a is %f", a); //output a is 1412.244019
a = [[NSString stringWithFormat:@"%.2f", a] floatValue];
NSLog(@"a is %f", a); //output a is 1412.239990
EDIT:
Scheint, als ob ich den Schwimmer nach der obigen Operation benutze, erachtet er es als 1412.240000, obwohl das NSLog etwas anderes sagt ... seltsam. Aber ich bekomme, was ich will, also ein dickes Lob für die verschwendete Zeit nichts zu jagen :)
EDIT Ich würde euch gerne alle als richtige Antworten auswählen, aber da ich nur eine auswählen kann, habe ich die erste gute Antwort mit zusätzlicher Erklärung (der beiden) ausgewählt zuletzt).
Hast du das versucht?
CGFloat val = 37.777779;
CGFloat rounded_down = floorf(val * 100) / 100; /* Result: 37.77 */
CGFloat nearest = floorf(val * 100 + 0.5) / 100; /* Result: 37.78 */
CGFloat rounded_up = ceilf(val * 100) / 100; /* Result: 37.78 */
source: Rundungszahl auf 2 Dezimalstellen in C
Ergänzung: Sie haben nur keine Kontrolle darüber, wie der Computer den Gleitkommawert speichert.
Diese gerundeten Werte sind also möglicherweise nicht GENAU die "offensichtlichen" Dezimalwerte, aber sie liegen sehr nahe beieinander, und das ist die maximale Garantie, die Sie haben werden.
Sie tun dies in Objective-C genauso wie in C:
double notRounded = ...;
double rounded = round (notRounded * 100.0) / 100.0;
Verwenden Sie float nicht - es sei denn, Sie können jemandem genau erklären, warum Sie float over double verwenden. Schwimmer hat eine sehr begrenzte Präzision. Und die Verwendung von Decke oder Boden ist dumm, da es eine perfekte Standardfunktion gibt, die als "rund" bezeichnet wird.
Weder float noch double können gena die meisten Dezimalwerte darstellen, wie z. B. 12.24. Da es eine viel höhere Präzision hat, können Sie mit double näher an 12.24 heranrücken. Daher besteht eine große Chance, dass NSLog eine seltsame Zahl für (float) 12.24 anzeigt, wie 12.23999997394 oder was auch immer, während es 12.24 für double anzeigt.
Fehler in dieser Zeile
a = [[NSString stringWithFormat:@"%.2f", a] floatValue];
korrigiere es zu
a = [NSString stringWithFormat:@"%.02f", a];
Der nächste Wert für 1412.24, den ein float
haben kann, ist 1412.239990234375. Es gibt eine no - Operation, die ein float
erzeugen kann, da das Format von float
-Objekten keine näheren Werte darstellt. Die Aufforderung, 1412.24 in float
darzustellen, entspricht der Aufforderung, 2.5 in int
darzustellen. Das geht einfach nicht.
Optionen für den Umgang damit sind:
float
zu ändern.double
verwenden, um näher zu kommen (viel näher), aber es wird immer noch nicht genau 1412.24 sein.float
Werte auf darstellbare Werte skalieren (z. B. in anderen Einheiten messen, sodass die gewünschten Werte in float
alle genau darstellbar sind).NSDecimal
.Sie können keinen Float-Wert erzwingen. Floats sind eher ungefähre Werte, da ihre Größe sehr groß sein kann. Da Sie nur so viele Bits verwenden können, kann sie nahe an eine Dezimalzahl heranreichen, diese aber nicht exakt ausdrücken.
Ein Vorschlag ist, alle Ihre Arithmetik in Ganzzahl, multipliziert mit 100, und dann zu teilen, wenn Sie Ihr Endergebnis anzeigen möchten. Möglicherweise sind die Zahlen zu groß, um dies zu verhindern.
Sie können a mit 100,0 multiplizieren und zum Runden 0,5 addieren und dann den int-Wert des Ergebnisses nehmen. Anschließend können Sie mit/100 den Wert vor dem Dezimalpunkt und mit% 100 die beiden Dezimalstellen abrufen.