Domanda

Esiste una funzione per arrotondare un float in C o devo scriverne una mia?

conversione galleggiante = 45.592346543;

Vorrei arrotondare il valore effettivo a una cifra decimale, conver = 45.6.

È stato utile?

Soluzione

Come ha detto Rob, probabilmente lo vorrai e basta stampa il float a 1 cifra decimale.In questo caso, puoi fare qualcosa di simile:

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

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

Se vuoi effettivamente arrotondare il valore memorizzato, è un po' più complicato.Per prima cosa, la tua rappresentazione con una cifra decimale raramente avrà un analogo esatto in virgola mobile.Se vuoi semplicemente avvicinarti il ​​più possibile, qualcosa di simile potrebbe fare al caso tuo:

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

Dubito che questo secondo esempio sia quello che stai cercando, ma l'ho incluso per completezza.Se hai bisogno di rappresentare i tuoi numeri in questo modo internamente e non solo sull'output, considera l'utilizzo di a rappresentazione in virgola fissa Invece.

Altri suggerimenti

Certo, puoi usare roundf () . Se vuoi arrotondare al primo decimale, puoi fare qualcosa del tipo: roundf(10 * x) / 10

#include <math.h>

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

Non dimenticare di collegarti con -lm. Vedi anche ceil (), floor () e trunc ().

Solo per generalizzare un po 'la risposta di Rob, se non stai non in output, puoi comunque usare la stessa interfaccia con sprintf().

Penso che ci sia un altro modo per farlo, però. Puoi provare ceil() e floor() per arrotondare su e giù. Un bel trucco è quello di aggiungere 0,5, quindi tutto ciò che supera 0,5 viene arrotondato per eccesso, ma qualsiasi cosa al di sotto viene arrotondata per difetto. double e truncf() funzionano solo su <=> s però

EDIT: Inoltre, per i float, puoi usare <=> per troncare i float. Lo stesso trucco +0.5 dovrebbe funzionare per fare arrotondamenti accurati.

Esiste una funzione round(), anche fround(), che arrotonderà all'intero più vicino espresso come doppio. Ma non è quello che vuoi.

Ho avuto lo stesso problema e ho scritto questo:

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

Per stampare un valore arrotondato, @Matt J risponde bene alla domanda.

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

Poiché la maggior parte dei virgola mobile (FP) è basata su binario , l'arrotondamento esatto su una posizione decimale non è possibile quando la risposta matematicamente corretta è x.1, x.2, ....

Per convertire il numero FP nel più vicino 0.1 è un'altra cosa.

Overflow : gli approcci che prima scala di 10 (o 100, 1000, ecc.) potrebbero traboccare per x.

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

Doppio arrotondamento : l'aggiunta di 0,5f e quindi l'utilizzo di floorf(x*10.0f + 0.5f)/10.0 restituisce il risultato errato quando la somma intermedia x*10.0f + 0.5f arrotonda per eccesso a un nuovo numero intero.

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

Trasmissione in int presenta l'ovvio problema quando float x è molto maggiore di INT_MAX.


L'uso di roundf() e della famiglia, disponibile in <math.h> è l'approccio migliore.

float round_tenthA(float x) {
  double x10 = 10.0 * x;
  return (float) (round(x10)/10.0);
}

Per evitare di usare double, verifica semplicemente se il numero deve essere arrotondato.

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

puoi usare #define round (a) (int) (a + 0,5) come macro  così ogni volta che scrivi round (1.6) restituisce 2 e ogni volta che scrivi round (1.3) restituisce 1.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top