Wie beschränke ich einen Gleitkommawert auf nur zwei Stellen nach dem Dezimalpunkt in C?

215

Wie kann ich einen Gleitkommawert (z. B. 37.777779) auf zwei Dezimalstellen (37.78) in C runden?

Sakib Arifin
quelle
15
Sie können die Zahl selbst nicht richtig runden, da float(und double) keine dezimalen Gleitkommazahlen sind - sie sind binäre Gleitkommazahlen -, sodass das Runden auf Dezimalstellen bedeutungslos ist. Sie können die Ausgabe jedoch runden.
Pavel Minaev
63
Es ist nicht bedeutungslos; es ist ungenau. Es gibt einen ziemlichen Unterschied.
Brooks Moses
2
Welche Art von Rundung erwarten Sie? Half-up oder Rundung auf die nächste gerade?
Wahrheitssucher Rangwan

Antworten:

407

Wenn Sie die Zahl nur für Ausgabezwecke runden möchten, "%.2f"ist die Formatzeichenfolge in der Tat die richtige Antwort. Wenn Sie jedoch den Gleitkommawert für die weitere Berechnung tatsächlich runden möchten, funktioniert Folgendes:

#include <math.h>

float val = 37.777779;

float rounded_down = floorf(val * 100) / 100;   /* Result: 37.77 */
float nearest = roundf(val * 100) / 100;  /* Result: 37.78 */
float rounded_up = ceilf(val * 100) / 100;      /* Result: 37.78 */

Beachten Sie, dass Sie möglicherweise drei verschiedene Rundungsregeln auswählen möchten: Abrunden (dh nach zwei Dezimalstellen abschneiden), auf die nächste gerundet und aufrunden. Normalerweise möchten Sie auf den nächsten runden.

Wie mehrere andere bereits betont haben, sind diese gerundeten Werte aufgrund der Besonderheiten der Gleitkommadarstellung möglicherweise nicht genau die "offensichtlichen" Dezimalwerte, liegen jedoch sehr nahe beieinander.

Weitere (viel!) Weitere Informationen zum Runden und insbesondere zu den Regeln für das Aufbrechen auf den nächsten Punkt finden Sie im Wikipedia-Artikel zum Runden .

Dale Hagglund
quelle
4
Kann es geändert werden, um das Runden mit beliebiger Genauigkeit zu unterstützen?
1
@slater Wenn Sie "willkürliche Genauigkeit" sagen, möchten Sie auf drei statt zwei Dezimalstellen runden oder Bibliotheken verwenden, die Dezimalwerte mit unbegrenzter Genauigkeit implementieren? Wenn erstere, nehmen Sie, wie ich hoffe, offensichtliche Anpassungen an der Konstanten 100 vor; Andernfalls führen Sie genau die oben gezeigten Berechnungen durch, nur mit der von Ihnen verwendeten Bibliothek mit mehreren Genauigkeiten.
Dale Hagglund
2
@ DaleHagglung Ersteres, danke. Ist die Einstellung, 100 durch pow (10, (int) gewünschte Präzision) zu ersetzen?
3
Ja. Verwenden Sie zum Runden nach k Dezimalstellen einen Skalierungsfaktor von 10 ^ k. Dies sollte wirklich leicht zu erkennen sein, wenn Sie einige Dezimalwerte von Hand schreiben und mit Vielfachen von 10 herumspielen. Angenommen, Sie arbeiten mit dem Wert 1.23456789 und möchten ihn auf 3 Dezimalstellen runden. Die Operation, die Ihnen zur Verfügung steht, ist rund bis ganzzahlig . Wie verschieben Sie die ersten drei Dezimalstellen so, dass sie vom Dezimalpunkt entfernt sind? Ich hoffe es ist klar, dass Sie mit 10 ^ 3 multiplizieren. Jetzt können Sie diesen Wert auf eine Ganzzahl runden. Als nächstes setzen Sie die drei Ziffern niedriger Ordnung zurück, indem Sie durch 10 ^ 3 teilen.
Dale Hagglund
1
Kann ich das doublesirgendwie auch zum Laufen bringen? Scheint nicht den Job zu machen, den ich will :( (mit floorund ceil).
Frau Niemand
87

Verwenden von % .2f in printf. Es werden nur 2 Dezimalstellen gedruckt.

Beispiel:

printf("%.2f", 37.777779);

Ausgabe:

37.77
Andrew Coleson
quelle
Dieser Weg ist besser, weil es keinen Präzisionsverlust gibt.
Albert
2
@albert Dies hat auch den Vorteil, dass keine floatReichweitenverluste auftreten, val * 100die überlaufen könnten.
chux
42

Angenommen, Sie sprechen über den Wert für das Drucken, dann sind die Antworten von Andrew Coleson und AraK richtig:

printf("%.2f", 37.777779);

Beachten Sie jedoch, dass dies keine gute Idee ist, wenn Sie die Zahl für den internen Gebrauch auf genau 37,78 runden möchten (z. B. um sie mit einem anderen Wert zu vergleichen). Dies ist aufgrund der Funktionsweise von Gleitkommazahlen normalerweise keine gute Idee Wenn Sie Gleichheitsvergleiche für Gleitkommawerte durchführen möchten, verwenden Sie stattdessen einen Zielwert +/- einen Sigma-Wert. Oder codieren Sie die Zahl als Zeichenfolge mit bekannter Genauigkeit und vergleichen Sie diese.

Siehe den Link in Greg Hewgills Antwort auf eine verwandte Frage , in der auch erläutert wird , warum Sie Gleitkommawerte nicht für Finanzberechnungen verwenden sollten.

John Carter
quelle
1
Upvoted für die Beantwortung der Frage hinter der Frage (oder der Frage, die hinter der Frage hätte stehen sollen!). Das ist ein ziemlich wichtiger Punkt.
Brooks Moses
Tatsächlich können 37,78 genau durch Gleitkomma dargestellt werden. Float hat 11 bis 12 Stellen für die Präzision. Das sollte ausreichen, um 3778 377.8 oder alle Arten von 4 Dezimalstellen zu adressieren.
Anonym Weiß
@HaryantoCiu ja fair genug, ich habe meine Antwort ein wenig bearbeitet.
John Carter
dynamische Präzision:printf("%.*f", (int)precision, (double)number);
Minhas Kamal
24

Wie wäre es damit:

float value = 37.777779;
float rounded = ((int)(value * 100 + .5) / 100.0);
Daniil
quelle
4
-1: a) Dies funktioniert nicht für negative Zahlen (ok, das Beispiel ist positiv, aber immer noch). b) Sie erwähnen nicht, dass es unmöglich ist, den genauen Dezimalwert im Float zu speichern
John Carter
32
@therefromhere: (a) Du hast recht (b) Was ist das? Ein Highschool-Test?
Daniil
1
Warum hast du 0,5 hinzugefügt?
Muhammad Tayyab
1
Es ist notwendig, Rundungsregeln zu befolgen.
Daniil
1
Rundungsregeln im Kontext des @ Daniil-Kommentars sind auf den nächsten gerundet
Shmil The Cat
20
printf("%.2f", 37.777779);

Wenn Sie in C-String schreiben möchten:

char number[24]; // dummy size, you should take care of the size!
sprintf(number, "%.2f", 37.777779);
AraK
quelle
@ Sinan: Warum die Bearbeitung? @AraK: Nein, du solltest auf die Größe achten :). Verwenden Sie snprintf ().
Aib
1
@aib: Ich würde raten, weil / ** / Kommentare im C-Stil sind und die Frage für C
Michael Haren
5
C89 nur erlaubt / ** / - Stil, C99 führte Unterstützung für // - Stil ein. Verwenden Sie einen lahmen / alten Compiler (oder erzwingen Sie den C89-Modus), und Sie können den // - Stil nicht verwenden. Nachdem dies gesagt wurde, ist es 2009, betrachten wir sie beide als C- und C ++ - Stil.
Andrew Coleson
11

Es gibt keine Möglichkeit, a floatauf einen anderen zu runden , floatda die Rundung floatmöglicherweise nicht darstellbar ist (eine Einschränkung der Gleitkommazahlen). Angenommen, Sie runden 37.777779 auf 37.78, aber die nächste darstellbare Zahl ist 37.781.

Sie können a jedoch floatmithilfe einer Formatzeichenfolgenfunktion "runden" .

Andrew Keeton
quelle
3
Dies unterscheidet sich nicht von der Aussage "Es gibt keine Möglichkeit, zwei Floats zu teilen und einen Float zu erhalten, da das geteilte Ergebnis möglicherweise nicht darstellbar ist", was zwar genau zutrifft, aber irrelevant ist. Floats sind immer ungenau, selbst für etwas so Grundlegendes wie Addition; Die Annahme ist immer, dass das, was Sie tatsächlich erhalten, "der Float ist, der der exakten gerundeten Antwort am nächsten kommt".
Brooks Moses
Was ich damit gemeint habe ist, dass Sie a nicht floatauf n Dezimalstellen runden können und dann erwarten, dass das Ergebnis immer n Dezimalstellen hat. Sie werden immer noch eine bekommen float, nur nicht die, die Sie erwartet haben.
Andrew Keeton
9

Wenn Sie C ++ verwenden, können Sie auch einfach eine Funktion wie die folgende erstellen:

string prd(const double x, const int decDigits) {
    stringstream ss;
    ss << fixed;
    ss.precision(decDigits); // set # places after decimal
    ss << x;
    return ss.str();
}

Sie können dann mit Code wie diesem ein beliebiges Double myDoublemit nStellen nach dem Dezimalpunkt ausgeben :

std::cout << prd(myDouble,n);
synaptik
quelle
7

Sie können weiterhin verwenden:

float ceilf(float x); // don't forget #include <math.h> and link with -lm.

Beispiel:

float valueToRound = 37.777779;
float roundedValue = ceilf(valueToRound * 100) / 100;
ZeroCool
quelle
Dies wird am Dezimalpunkt abgeschnitten (dh es werden 37 erzeugt), und er muss auf zwei Stellen nach dem Dezimalpunkt runden .
Pavel Minaev
Das Runden auf zwei Stellen nach dem Dezimalpunkt ist jedoch eine triviale Variation (sollte aber dennoch in der Antwort erwähnt werden; ZeroCool, möchten Sie eine Bearbeitung hinzufügen?): Float roundValue = Ceilf (valueToRound * 100.0) / 100.0;
Brooks Moses
In einen Schlafzustand :)
ZeroCool
Wie kommt es, dass diese Lösung nicht beliebter ist? Dies funktioniert genau so, wie es mit minimalem Code sein sollte. Gibt es eine Einschränkung?
Andy
7

In C ++ (oder in C mit Casts im C-Stil) können Sie die folgende Funktion erstellen:

/* Function to control # of decimal places to be output for x */
double showDecimals(const double& x, const int& numDecimals) {
    int y=x;
    double z=x-y;
    double m=pow(10,numDecimals);
    double q=z*m;
    double r=round(q);

    return static_cast<double>(y)+(1.0/m)*r;
}

Dann std::cout << showDecimals(37.777779,2);würde produzieren: 37,78.

Natürlich müssen Sie nicht wirklich alle 5 Variablen in dieser Funktion erstellen, aber ich lasse sie dort, damit Sie die Logik sehen können. Es gibt wahrscheinlich einfachere Lösungen, aber das funktioniert gut für mich - zumal ich die Anzahl der Stellen nach der Dezimalstelle nach Bedarf anpassen kann.

synaptik
quelle
5

Verwenden Sie dazu immer die printfFunktionsfamilie. Selbst wenn Sie den Wert als Float erhalten möchten, verwenden Sie am besten snprintfden gerundeten Wert als Zeichenfolge und analysieren ihn anschließend mit atof:

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

double dround(double val, int dp) {
    int charsNeeded = 1 + snprintf(NULL, 0, "%.*f", dp, val);
    char *buffer = malloc(charsNeeded);
    snprintf(buffer, charsNeeded, "%.*f", dp, val);
    double result = atof(buffer);
    free(buffer);
    return result;
}

Ich sage dies, weil der Ansatz, den die derzeit am besten gewählte Antwort und einige andere hier zeigen - Multiplizieren mit 100, Runden auf die nächste ganze Zahl und erneutes Teilen durch 100 - in zweierlei Hinsicht fehlerhaft ist:

  • Bei einigen Werten wird in die falsche Richtung gerundet, da durch die Multiplikation mit 100 die Dezimalstelle, die die Rundungsrichtung bestimmt, aufgrund der Ungenauigkeit der Gleitkommazahlen von 4 auf 5 oder umgekehrt geändert wird
  • Bei einigen Werten führt das Multiplizieren und anschließende Teilen durch 100 nicht zu einem Roundtrip, was bedeutet, dass das Endergebnis falsch ist, selbst wenn keine Rundung stattfindet

Führen Sie dieses Programm aus, um die erste Art von Fehler zu veranschaulichen - die Rundungsrichtung ist manchmal falsch.

int main(void) {
    // This number is EXACTLY representable as a double
    double x = 0.01499999999999999944488848768742172978818416595458984375;

    printf("x: %.50f\n", x);

    double res1 = dround(x, 2);
    double res2 = round(100 * x) / 100;

    printf("Rounded with snprintf: %.50f\n", res1);
    printf("Rounded with round, then divided: %.50f\n", res2);
}

Sie sehen diese Ausgabe:

x: 0.01499999999999999944488848768742172978818416595459
Rounded with snprintf: 0.01000000000000000020816681711721685132943093776703
Rounded with round, then divided: 0.02000000000000000041633363423443370265886187553406

Beachten Sie, dass der Wert, mit dem wir begonnen haben, weniger als 0,015 betrug. Daher lautet die mathematisch korrekte Antwort beim Runden auf 2 Dezimalstellen 0,01. Natürlich ist 0,01 nicht genau als Double darstellbar, aber wir erwarten, dass unser Ergebnis das Double ist, das 0,01 am nächsten kommt. Die Verwendung snprintfgibt uns dieses Ergebnis, aber die Verwendung round(100 * x) / 100gibt uns 0,02, was falsch ist. Warum? Denn 100 * xgibt uns genau 1,5 als Ergebnis. Das Multiplizieren mit 100 ändert somit die richtige Richtung zum Runden.

Um die zweite Art von Fehler zu veranschaulichen - das Ergebnis ist manchmal falsch * 100und / 100nicht wirklich umgekehrt - können wir eine ähnliche Übung mit einer sehr großen Anzahl durchführen:

int main(void) {
    double x = 8631192423766613.0;

    printf("x: %.1f\n", x);

    double res1 = dround(x, 2);
    double res2 = round(100 * x) / 100;

    printf("Rounded with snprintf: %.1f\n", res1);
    printf("Rounded with round, then divided: %.1f\n", res2);
}

Unsere Zahl hat jetzt nicht einmal einen Bruchteil; Es ist ein ganzzahliger Wert, der nur mit Typ gespeichert wird double. Das Ergebnis nach dem Runden sollte also dieselbe Zahl sein, mit der wir begonnen haben, oder?

Wenn Sie das obige Programm ausführen, sehen Sie:

x: 8631192423766613.0
Rounded with snprintf: 8631192423766613.0
Rounded with round, then divided: 8631192423766612.0

Hoppla. Unsere snprintfMethode liefert wieder das richtige Ergebnis, aber der Ansatz "Multiplizieren, Runden, Teilen" schlägt fehl. Das ist , weil der mathematisch korrekte Wert 8631192423766613.0 * 100, 863119242376661300.0ist nicht exakt darstellbar als Doppel; der nächste Wert ist 863119242376661248.0. Wenn Sie das durch 100 teilen, erhalten Sie 8631192423766612.0- eine andere Zahl als die, mit der Sie begonnen haben.

Hoffentlich ist dies eine ausreichende Demonstration, dass die Verwendung roundfzum Runden auf eine Anzahl von Dezimalstellen fehlerhaft ist und dass Sie snprintfstattdessen verwenden sollten. Wenn sich das für Sie wie ein schrecklicher Hack anfühlt, werden Sie vielleicht durch das Wissen beruhigt sein, dass es im Grunde das ist, was CPython tut .

Mark Amery
quelle
+1 für ein konkretes Beispiel dafür, was mit meiner Antwort und ähnlichen Antworten schief geht, dank der Verrücktheit des IEEE-Gleitkommas und der Bereitstellung einer einfachen Alternative. Ich war mir vor langer Zeit peripher bewusst, wie viel Aufwand in den Druck gesteckt wurde, und Freunde waren mir sicher, dass sie Gleitkommawerte umrunden konnten. Ich würde vermuten, dass die damals geleistete Arbeit hier auftaucht.
Dale Hagglund
Ähm ... Entschuldigung für das Wort Salat gegen Ende, das jetzt zu spät zum Bearbeiten ist. Was ich sagen wollte war "... viel Mühe in printf und Freunde gesteckt, um sie sicher zu machen ..."
Dale Hagglund
4

Verwenden Sie float roundf(float x).

"Die Rundungsfunktionen runden ihr Argument im Gleitkommaformat auf den nächsten ganzzahligen Wert und runden Fälle unabhängig von der aktuellen Rundungsrichtung auf halbem Weg von Null weg." C11dr §7.12.9.5

#include <math.h>
float y = roundf(x * 100.0f) / 100.0f; 

Abhängig von Ihrer floatImplementierung sind Zahlen, die auf halbem Weg zu sein scheinen, nicht. als Gleitkomma ist typischerweise Basis-2-orientiert. Darüber hinaus 0.01ist es am schwierigsten, in allen "halben" Fällen genau auf das nächste zu runden .

void r100(const char *s) {
  float x, y;
  sscanf(s, "%f", &x);
  y = round(x*100.0)/100.0;
  printf("%6s %.12e %.12e\n", s, x, y);
}

int main(void) {
  r100("1.115");
  r100("1.125");
  r100("1.135");
  return 0;
}

 1.115 1.115000009537e+00 1.120000004768e+00  
 1.125 1.125000000000e+00 1.129999995232e+00
 1.135 1.134999990463e+00 1.139999985695e+00

Obwohl "1.115" zwischen 1.11 und 1.12 "auf halbem Weg" liegt, floatist 1.115000009537...und ist der Wert bei der Umrechnung in " nicht mehr" auf halbem Weg ", sondern näher an 1.12 und rundet auf den nächsten Wert floatvon1.120000004768...

"1.125" ist "auf halbem Weg" zwischen 1.12 und 1.13, wenn in konvertiert, floatist der Wert genau 1.125und ist "auf halbem Weg". Es rundet in Richtung 1,13, weil es gleichmäßige Regeln gibt, und rundet auf das nächste floatvon1.129999995232...

Obwohl "1.135" zwischen 1.13 und 1.14 "auf halbem Weg" liegt, floatist 1.134999990463...und ist der Wert bei der Konvertierung in "nicht auf halbem Weg", sondern näher an 1.13 und rundet auf den nächsten Wert floatvon1.129999995232...

Wenn Code verwendet wird

y = roundf(x*100.0f)/100.0f;

Obwohl „1,135“ ist „ auf halbem Wege“ zwischen 1,13 und 1,14, wenn umgewandelt float, der Wert 1.134999990463...und ist nicht mehr „ auf halbem Wege“, aber näher an 1,13 aber falsch Runden floatder 1.139999985695...aufgrund der begrenzteren Genauigkeit floatvs. double. Dieser falsche Wert kann abhängig von den Codierungszielen als korrekt angesehen werden.

chux - Monica wieder einsetzen
quelle
4

Ich habe dieses Makro zum Runden von Float-Zahlen erstellt. Fügen Sie es in Ihren Header / Sein der Datei ein

#define ROUNDF(f, c) (((float)((int)((f) * (c))) / (c)))

Hier ist ein Beispiel:

float x = ROUNDF(3.141592, 100)

x entspricht 3,14 :)

mou
quelle
Dies wird abgeschnitten, aber die Frage fordert eine Rundung an. Darüber hinaus kann es bei Gleitkommaoperationen zu Rundungsfehlern kommen.
Eric Postpischil
3
double f_round(double dval, int n)
{
    char l_fmtp[32], l_buf[64];
    char *p_str;
    sprintf (l_fmtp, "%%.%df", n);
    if (dval>=0)
            sprintf (l_buf, l_fmtp, dval);
    else
            sprintf (l_buf, l_fmtp, dval);
    return ((double)strtod(l_buf, &p_str));

}

Hier nist die Anzahl der Dezimalstellen

Beispiel:

double d = 100.23456;

printf("%f", f_round(d, 4));// result: 100.2346

printf("%f", f_round(d, 2));// result: 100.23
user2331026
quelle
-1 aus vier Gründen: 1) das Fehlen einer Erklärung, 2) die Anfälligkeit für Pufferüberlauf - dies wird überlaufen und daher möglicherweise abstürzen, wenn dvales riesig ist 3) das Unheimliche if/ elseBlockieren, bei dem Sie in jedem Zweig genau dasselbe tun und 4) die überkomplizierte Verwendung sprintfzum Erstellen des Formatbezeichners für einen zweiten sprintfAufruf; Es ist einfacher, nur .*den doppelten Wert und die Anzahl der Dezimalstellen als Argumente für denselben sprintfAufruf zu verwenden und zu übergeben.
Mark Amery
3

Code-Definition:

#define roundz(x,d) ((floor(((x)*pow(10,d))+.5))/pow(10,d))

Ergebnisse :

a = 8.000000
sqrt(a) = r = 2.828427
roundz(r,2) = 2.830000
roundz(r,3) = 2.828000
roundz(r,5) = 2.828430
Zyp Datenschutz
quelle
0

Lassen Sie mich zunächst versuchen, meinen Grund für die Hinzufügung einer weiteren Antwort auf diese Frage zu rechtfertigen. In einer idealen Welt ist das Runden keine große Sache. In realen Systemen müssen Sie sich jedoch möglicherweise mit mehreren Problemen auseinandersetzen, die zu Rundungen führen können, die möglicherweise nicht Ihren Erwartungen entsprechen. Beispielsweise führen Sie möglicherweise Finanzberechnungen durch, bei denen die Endergebnisse gerundet und den Benutzern als 2 Dezimalstellen angezeigt werden. Dieselben Werte werden mit fester Genauigkeit in einer Datenbank gespeichert, die mehr als 2 Dezimalstellen enthalten kann (aus verschiedenen Gründen; es gibt keine optimale Anzahl von Stellen, die beibehalten werden müssen ... hängt von bestimmten Situationen ab, die jedes System unterstützen muss, z. B. winzigen Elementen, deren Preise sind Bruchteile eines Pennys pro Einheit); und Gleitkommaberechnungen, die an Werten durchgeführt werden, bei denen die Ergebnisse plus / minus epsilon sind. Ich habe mich im Laufe der Jahre mit diesen Problemen auseinandergesetzt und meine eigene Strategie entwickelt. Ich werde nicht behaupten, dass ich mich jedem Szenario gestellt habe oder die beste Antwort habe, aber im Folgenden finden Sie ein Beispiel für meinen bisherigen Ansatz, der diese Probleme überwindet:

Angenommen, 6 Dezimalstellen werden als ausreichende Genauigkeit für Berechnungen von Floats / Doubles (eine willkürliche Entscheidung für die spezifische Anwendung) unter Verwendung der folgenden Rundungsfunktion / -methode angesehen:

double Round(double x, int p)
{
    if (x != 0.0) {
        return ((floor((fabs(x)*pow(double(10.0),p))+0.5))/pow(double(10.0),p))*(x/fabs(x));
    } else {
        return 0.0;
    }
}

Das Runden auf 2 Dezimalstellen zur Darstellung eines Ergebnisses kann wie folgt durchgeführt werden:

double val;
// ...perform calculations on val
String(Round(Round(Round(val,8),6),2));

Das val = 6.825Ergebnis ist 6.83wie erwartet.

Denn das val = 6.824999Ergebnis ist 6.82. Hier wird davon ausgegangen, dass die Berechnung genau ergab 6.824999und die 7. Dezimalstelle Null ist.

Denn das val = 6.8249999Ergebnis ist 6.83. Die 7. Dezimalstelle 9in diesem Fall bewirkt, dass die Round(val,6)Funktion das erwartete Ergebnis liefert. In diesem Fall kann es eine beliebige Anzahl von nachgestellten 9s geben.

Denn das val = 6.824999499999Ergebnis ist 6.83. Das Runden auf die 8. Dezimalstelle als erster Schritt, dh Round(val,8)das Behandeln des einen bösen Falls, bei dem ein berechnetes Gleitkommaergebnis berechnet wird 6.8249995, aber intern als dargestellt wird 6.824999499999....

Schließlich ist das Beispiel von der Frage ... val = 37.777779ergibt 37.78.

Dieser Ansatz könnte weiter verallgemeinert werden als:

double val;
// ...perform calculations on val
String(Round(Round(Round(val,N+2),N),2));

Dabei ist N die Genauigkeit, die für alle Zwischenberechnungen für Floats / Doubles beibehalten werden muss. Dies funktioniert auch bei negativen Werten. Ich weiß nicht, ob dieser Ansatz für alle Möglichkeiten mathematisch korrekt ist.

Tim D.
quelle
0

Einfacher C-Code zum Runden einer Zahl:

float n = 3.56;
printf("%.f", n);

Dies wird Folgendes ausgeben:

4
Aqeel Shamsudheen
quelle
-1

... oder Sie können es auf die altmodische Weise ohne Bibliotheken tun:

float a = 37.777779;

int b = a; // b = 37    
float c = a - b; // c = 0.777779   
c *= 100; // c = 77.777863   
int d = c; // d = 77;    
a = b + d / (float)100; // a = 37.770000;

Das natürlich, wenn Sie die zusätzlichen Informationen aus der Nummer entfernen möchten.

NikosD
quelle
-2

Diese Funktion nimmt die Zahl und Genauigkeit und gibt die gerundete Zahl zurück

float roundoff(float num,int precision)
{
      int temp=(int )(num*pow(10,precision));
      int num1=num*pow(10,precision+1);
      temp*=10;
      temp+=5;
      if(num1>=temp)
              num1+=10;
      num1/=10;
      num1*=10;
      num=num1/pow(10,precision+1);
      return num;
}

Es konvertiert die Gleitkommazahl in int, indem es den Punkt nach links verschiebt und nach der Bedingung größer als fünf sucht.

kapil
quelle