Um Drucken einen gerundeten Wert, @Matt J gut beantwortet die Frage.
float x = 45.592346543;
printf("%0.1f\n", x); // 45.6
Da die meisten Gleitkomma (FP) ist binäres basiert, genaue einem decimal Ort Rundung ist nicht möglich, wenn die mathematisch korrekte Antwort x.1, x.2, ...
ist.
Um die FP-Nummer in die nächste0.1
konvertieren ist eine andere Frage.
Überlauf: Ansätze, die zuerst um 10 (oder 100, 1000 usw.) skalieren, können für große x
überlaufen.
float round_tenth1(float x) {
x = x * 10.0f;
...
}
Doppel Abrunden: 0,5f Hinzufügen und dann unter Verwendung von floorf(x*10.0f + 0.5f)/10.0
gibt das falsche Ergebnis, wenn die Zwischensumme x*10.0f + 0.5f
Runden bis zu einer neuen Ganzzahl.
// Fails to round 838860.4375 correctly, comes up with 838860.5
// 0.4499999880790710449 fails as it rounds to 0.5
float round_tenth2(float x) {
if (x < 0.0) {
return ceilf(x*10.0f + 0.5f)/10.0f;
}
return floorf(x*10.0f + 0.5f)/10.0f;
}
zu int
Casting hat das offensichtliche Problem, wenn float x
viel größer als INT_MAX
ist.
Mit roundf()
und Familie, in <math.h>
ist der beste Ansatz.
float round_tenthA(float x) {
double x10 = 10.0 * x;
return (float) (round(x10)/10.0);
}
Um zu vermeiden, double
verwenden, testen einfach, wenn die Zahl gerundet werden muss.
float round_tenthB(float x) {
const float limit = 1.0/FLT_EPSILON;
if (fabsf(x) < limit) {
return roundf(x*10.0f)/10.0f;
}
return x;
}
Runden scheint zu funktionieren OK, aber zum Beispiel rund 45,569346543; ist 45.599998 .... oder 45.5 mit * 1.0f .... ich bin näher dran gedacht, muss noch mal Boden und Decke lesen. danke Leute. –
Es kommt von Floating-Point-Ungenauigkeit, ich wechselte zu Double, funktioniert super. Vielen Dank. –
Nur um Matt Js Schlusskommentar zu wiederholen, von dem ich nicht sicher bin, ob er absorbiert wurde: 45.6 kann nicht genau in einem binären Gleitkommaformat dargestellt werden, so dass das nicht gespeichert wird, selbst wenn du double verwendest. Wenn Ihr Programm jetzt "45.6" druckt, liegt das daran, dass die Ausgabe-Routinen es für Sie runden. – Spike0xff