2009-01-30 5 views

Antwort

23

Wie Rob erwähnt, möchten Sie wahrscheinlich nur Drucken der Schwimmer auf 1 Dezimalstelle.

#include <stdio.h> 
#include <stdlib.h> 

int main() 
{ 
    float conver = 45.592346543; 
    printf("conver is %0.1f\n",conver); 
    return 0; 
} 

Wenn Sie wollen tatsächlich um den gespeicherten Wert, dass ein wenig komplizierter ist: In diesem Fall können Sie so etwas wie die folgenden tun. Zum einen wird Ihre Ein-Dezimalstellen-Darstellung selten ein exaktes Analog in Gleitkomma haben. Wenn Sie nur so nah wie möglich erhalten möchten, so etwas wie dies könnte den Trick tun:

#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, dieses zweite Beispiel ist das, was Sie suchen, aber ich schloss es auf Vollständigkeit. Wenn Sie Ihre Zahlen intern und nicht nur bei der Ausgabe intern darstellen müssen, sollten Sie stattdessen eine fixed-point representation verwenden.

+0

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. –

+0

Es kommt von Floating-Point-Ungenauigkeit, ich wechselte zu Double, funktioniert super. Vielen Dank. –

+0

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

1
#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().

+0

die auf die nächste Ganzzahl runden ... nicht das, wonach er fragte. –

+0

das ist richtig, ich bin mir selbst voraus. Ich wählte Eduard's Antwort. –

27

Sicher können Sie roundf() verwenden. Wenn Sie auf eine Dezimalstelle runden mögen, dann könnte man so etwas wie: roundf(10 * x)/10

+1

Schön, alle anderen ignorierten die Tatsache, dass der Fragesteller nicht nach der nächsten Ganzzahl fragte. Es sollte bemerkt werden, dass wegen der Ungenauigkeit im Fließkomma. Beim Drucken wird in diesem Beispiel wahrscheinlich "45.59999" angezeigt. –

+0

Eine schönere allgemeinere Lösung wäre: double f (double x, int Dezimalpunkte) {int n = pow (10, decimal_points); Rücklaufrunde (n * x)/n; } –

+0

nicht aufgelöste externe symbol _roundf referenziert in funktion _f haben math.h enthalten aber es mag roundf nicht() ich bin in VS.NET, ist Foundf nur für linux? –

1

Nur um Robs Antwort ein wenig zu verallgemeinern, wenn man nicht ist es bei der Ausgabe zu tun, können Sie immer noch die gleiche Schnittstelle mit sprintf() .

Ich denke, es gibt eine andere Möglichkeit, es zu tun. Sie können versuchen, ceil() und floor() aufzurunden und abzurunden. Ein netter Trick ist es, 0,5 hinzuzufügen, also alles über 0,5 Runden, aber alles darunter rundet ab. ceil() und floor() arbeiten nur an double s obwohl.

BEARBEITEN: Auch für Floats können Sie truncf() verwenden, um Floats zu trunkieren. Derselbe + 0,5 Trick sollte funktionieren, um eine genaue Rundung durchzuführen.

+0

Sie können 'ceilf()' und 'floorf()' und 'roundf()' jeweils für Floats verwenden. – uchuugaka

+0

"Ein schöner Trick ist es, 0,5 hinzuzufügen", scheitert in vielen Fällen: [siehe Kommentar] (http://stackoverflow.com/questions/497018/is-there-a-function-to-round-a-float-in -c-oder-ich-brauche-ich-schreibe-meine-eigene # comment57895810_497037). – chux

1

Es gibt eine round() Funktion, auch fround(), die auf die nächste ganze Zahl aufrundet, ausgedrückt als ein Doppel. Aber das ist nicht was du willst.

hatte ich das gleiche Problem und schrieb dies:

#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; 
} 
0

Sie #define Runde (a) (int) (a + 0,5) als Makro so, wann immer Sie es rund schreiben (1.6) verwenden können, gibt 2 und immer wenn Sie rund schreiben (1.3) gibt es 1 zurück.

0

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; 
} 
Verwandte Themen