Gibt es eine Funktion einen Schwimmer in C runden oder muß ich meine eigenen schreiben?

StackOverflow https://stackoverflow.com/questions/497018

  •  20-08-2019
  •  | 
  •  

Frage

Gibt es eine Funktion einen Schwimmer in C runden oder muß ich meine eigenen schreiben?

  

= float conver 45 59 2.346.543;

Ich möchte den tatsächlichen Wert auf eine Dezimalstelle runden, conver = 45 6 .

War es hilfreich?

Lösung

Wie Rob erwähnt, werden Sie wahrscheinlich wollen einfach nur Drucken der Schwimmer auf 1 Dezimalstelle. In diesem Fall können Sie so etwas wie die folgenden tun:

#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, das ist ein wenig komplizierter. Zum einen Ihr One-Dezimal-Platz Darstellung haben selten eine genaue analoge in Gleitkommaoperationen. 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 benötigen Sie intern Ihre Zahlen auf diese Weise darstellen, und nicht nur auf die Produktion, sollten Sie einen fest Punktdarstellung statt.

Andere Tipps

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

#include <math.h>

double round(double x);
float roundf(float x);

Vergessen Sie nicht, mit -Im zu verknüpfen. Siehe auch ceil (), Boden () und trunc ().

Just Robs Antwort ein wenig zu verallgemeinern, wenn Sie nicht auf Ausgang zu tun, haben Sie immer die gleiche Schnittstelle mit sprintf() verwenden können.

Ich denke, es gibt einen anderen Weg, es zu tun, wenn. Sie können ceil() und floor() versuchen abzurunden nach oben und unten. Ein schöner Trick ist 0,5 hinzuzufügen, so etwas über 0,5 Runden, aber etwas darunter abrundet. ceil() und floor() nur wenn auf doubles arbeiten.

EDIT: Auch für Schwimmer, können Sie truncf() verwenden, um Schwimmer gestutzt. Der gleiche +0,5 Trick sollte genaue Runden einiges zu tun.

Es gibt eine round() Funktion, auch fround(), das wird rund um die nächste ganze Zahl als Doppel ausgedrückt. Aber das ist nicht das, was Sie wollen.

Ich hatte 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;
} 

Drucken ein gerundeter Wert, @ Matt J auch die Frage beantwortet.

float x = 45.592346543;
printf("%0.1f\n", x);  // 45.6

Wie die meisten Gleitkomma (FP) ist binary basiert, genau Rundung auf eine dezimal Ort nicht möglich ist, wenn die mathematisch korrekte Antwort ist, x.1, x.2, ....

die FP-Zahl zu der am nächsten konvertieren 0.1 ist eine andere Sache.

Überlauf . Ansätze, die erste Skala von 10 (oder 100, 1000, etc.) kann für großen Überlauf x

float round_tenth1(float x) {
  x = x * 10.0f;
  ...
}

Doppelrundung :. 0,5f Hinzufügen und dann floorf(x*10.0f + 0.5f)/10.0 Verwendung gibt das falsche Ergebnis, wenn die Zwischensumme x*10.0f + 0.5f auf eine neue ganze Zahl aufgerundet

// 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;
}

Casting zu int 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, einfach zu testen, ob die Zahl braucht Rundung.

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

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

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top