Gibt es eine Funktion zum Runden eines Floats in C oder muss ich meine eigene schreiben?

Lesezeit: 6 Minuten

Benutzer-Avatar
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

Benutzer-Avatar
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 doubleist 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.

Benutzer-Avatar
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 doubletesten 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;
}

Benutzer-Avatar
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;
} 

Benutzer-Avatar
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.

1365650cookie-checkGibt es eine Funktion zum Runden eines Floats in C oder muss ich meine eigene schreiben?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy