Gibt es eine Funktion zum Runden eines Floats in C oder muss ich meine eigene schreiben?
float conver = 45.592346543;
Ich möchte den tatsächlichen Wert auf eine Dezimalstelle runden, conver = 45.6.
TTT
Gibt es eine Funktion zum Runden eines Floats in C oder muss ich meine eigene schreiben?
float conver = 45.592346543;
Ich möchte den tatsächlichen Wert auf eine Dezimalstelle runden, conver = 45.6.
Klar kannst du verwenden runden(). Wenn Sie auf eine Dezimalstelle runden möchten, können Sie Folgendes tun: roundf(10 * x) / 10
Schön, alle anderen haben die Tatsache ignoriert, dass der Fragesteller nicht darum gebeten hat, auf die nächste Ganzzahl zu runden. Es sollte beachtet werden, dass wegen der Ungenauigkeit im Fließkomma. Beim Drucken sehen Sie im Beispiel wahrscheinlich “45.59999”.
– Evan Teran
30. Januar 2009 um 20:13 Uhr
Eine schöne allgemeinere Lösung wäre: double f(double x, int decimal_points) { int n = pow(10, decimal_points); return roundf(n * x) / n; }
– Evan Teran
30. Januar 2009 um 20:15 Uhr
nicht aufgelöstes externes Symbol _roundf, auf das in Funktion _f verwiesen wird, hat math.h enthalten, aber es mag nicht roundf() Ich bin in VS .NET, ist foundf nur für Linux?
– TTT
30. Januar 2009 um 20:45 Uhr
Tommy, roundf() ist in C99 definiert, also sollte jeder konforme Compiler es unterstützen. Vielleicht verlinken Sie nicht mit der Mathematikbibliothek?
– Eduard-Gabriel Munteanu
30. Januar 2009 um 21:09 Uhr
Ich glaube nicht, dass die neueren Visual Studios irgendwelche Anstrengungen unternommen haben, um C99 zu unterstützen.
– Evan Teran
31. Januar 2009 um 3:31 Uhr
Wie Rob erwähnt hat, möchten Sie wahrscheinlich nur drucken der Schwimmer auf 1 Dezimalstelle. In diesem Fall können Sie Folgendes tun:
#include <stdio.h>
#include <stdlib.h>
int main()
{
float conver = 45.592346543;
printf("conver is %0.1f\n",conver);
return 0;
}
Wenn Sie den gespeicherten Wert tatsächlich runden möchten, ist das etwas komplizierter. Zum einen wird Ihre Darstellung mit einer Dezimalstelle selten ein exaktes Analogon in Gleitkommazahlen haben. Wenn Sie nur so nah wie möglich kommen wollen, könnte so etwas ausreichen:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main()
{
float conver = 45.592346543;
printf("conver is %0.1f\n",conver);
conver = conver*10.0f;
conver = (conver > (floor(conver)+0.5f)) ? ceil(conver) : floor(conver);
conver = conver/10.0f;
//If you're using C99 or better, rather than ANSI C/C89/C90, the following will also work.
//conver = roundf(conver*10.0f)/10.0f;
printf("conver is now %f\n",conver);
return 0;
}
Ich bezweifle, dass dieses zweite Beispiel das ist, wonach Sie suchen, aber ich habe es der Vollständigkeit halber eingefügt. Wenn Sie Ihre Zahlen intern und nicht nur bei der Ausgabe auf diese Weise darstellen möchten, sollten Sie die Verwendung von a in Betracht ziehen Festkommadarstellung stattdessen.
Das Abrunden scheint OK zu funktionieren, aber zum Beispiel das Runden von 45,569346543; ist 45,599998 …. oder 45,5 mit * 1,0f …. Ich bin näher dran, muss Boden und Decke noch einmal lesen. danke Leute.
– TTT
30. Januar 2009 um 21:04 Uhr
Es kommt von der Ungenauigkeit des Gleitkommas, ich habe es auf Double geändert, funktioniert großartig. Vielen Dank.
– TTT
30. Januar 2009 um 22:46 Uhr
Nur um den abschließenden Kommentar von Matt J zu wiederholen, von dem ich nicht sicher bin, ob Sie ihn verstanden haben: 45,6 kann in KEINEM binären Gleitkommaformat genau dargestellt werden, also wird das nicht gespeichert, selbst wenn Sie double verwenden. Wenn Ihr Programm jetzt “45,6” ausgibt, liegt das daran, dass die Ausgaberoutinen es für Sie runden.
– Spike0xff
23. Dezember 2013 um 18:20 Uhr
(conver >= (floor(conver)+0.5f)) ? ceil(conver) : floor(conver)
ist äquivalent zu floor(conver+0.5f)
(ich glaube, du meinst es genau >=
nicht >
).
– Timofey Gorshkov
21. November 2014 um 12:13 Uhr
Es ist auch besser, dies zu tun: conver>0f ? floor(conver+0.5f) : ceil(conver-0.5f)
— auch mit Negativen zu arbeiten.
– Timofey Gorshkov
21. November 2014 um 12:18 Uhr
Joao da Silva
#include <math.h>
double round(double x);
float roundf(float x);
Vergessen Sie nicht, mit -lm zu verknüpfen. Siehe auch ceil(), floor() und trunc().
diese Rundung auf die nächste Ganzzahl … nicht das, wonach er gefragt hat.
– Evan Teran
30. Januar 2009 um 20:10 Uhr
das ist richtig, ich habe mich selbst überholt. Ich habe für Eduards Antwort gestimmt.
– João da Silva
30. Januar 2009 um 20:11 Uhr
Nur um Robs Antwort ein wenig zu verallgemeinern, wenn Sie es sind nicht Wenn Sie dies bei der Ausgabe tun, können Sie immer noch dieselbe Schnittstelle verwenden sprintf()
.
Ich denke aber, dass es auch anders geht. Du kannst es versuchen ceil()
und floor()
auf- und abzurunden. Ein netter Trick besteht darin, 0,5 zu addieren, sodass alles über 0,5 aufgerundet wird, aber alles darunter abgerundet wird. ceil()
und floor()
nur weiterarbeiten double
ist doch.
EDIT: Auch für Schwimmer können Sie verwenden truncf()
Floats abzuschneiden. Derselbe +0,5-Trick sollte funktionieren, um eine genaue Rundung durchzuführen.
Chux – Wiedereinsetzung von Monica
Zu drucken ein gerundeter Wert, @Matt J beantwortet die Frage gut.
float x = 45.592346543;
printf("%0.1f\n", x); // 45.6
Da die meisten Gleitkommazahlen (FP) sind binär basierend, genau auf eins runden Dezimal Ort ist nicht möglich, wenn die mathematisch richtige Antwort ist x.1, x.2, ...
.
Um die FP-Nummer in die umzuwandeln nächste 0.1
ist eine andere Sache.
Überlauf: Ansätze, die zuerst um 10 (oder 100, 1000 usw.) skalieren, können für große überlaufen x
.
float round_tenth1(float x) {
x = x * 10.0f;
...
}
Doppelte Rundung: 0,5f hinzufügen und dann verwenden floorf(x*10.0f + 0.5f)/10.0
liefert bei der Zwischensumme das falsche Ergebnis x*10.0f + 0.5f
rundet auf eine neue Ganzzahl auf.
// 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;
}
Gießen zu int
hat das offensichtliche Problem wann float x
ist viel größer als INT_MAX
.
Verwenden roundf()
und Familie, erhältlich in <math.h>
ist der beste Ansatz.
float round_tenthA(float x) {
double x10 = 10.0 * x;
return (float) (round(x10)/10.0);
}
Um die Verwendung zu vermeiden double
testen Sie einfach, ob 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;
}
Garret Hyde
Da ist ein round()
Funktion auch fround()
, wodurch auf die nächste ganze Zahl gerundet wird, die als Double ausgedrückt wird. Aber das ist nicht das, was Sie wollen.
Ich hatte das gleiche Problem und schrieb folgendes:
#include <math.h>
double db_round(double value, int nsig)
/* ===============
**
** Rounds double <value> to <nsig> significant figures. Always rounds
** away from zero, so -2.6 to 1 sig fig will become -3.0.
**
** <nsig> should be in the range 1 - 15
*/
{
double a, b;
long long i;
int neg = 0;
if(!value) return value;
if(value < 0.0)
{
value = -value;
neg = 1;
}
i = nsig - log10(value);
if(i) a = pow(10.0, (double)i);
else a = 1.0;
b = value * a;
i = b + 0.5;
value = i / a;
return neg ? -value : value;
}
rotes Blut
Sie können #define round(a) (int) (a+0.5) als Makro verwenden. Wenn Sie also round(1.6) schreiben, wird 2 zurückgegeben, und wenn Sie round(1.3) schreiben, wird 1 zurückgegeben.