2009-01-30 7 views

Respuesta

23

Como mencionó Rob, probablemente solo desee imprimir el flotador a 1 lugar decimal. En este caso, se puede hacer algo como lo siguiente:

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

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

Si desea realmente alrededor del valor almacenado, que es un poco más complicado. Por un lado, su representación de un lugar decimal raramente tendrá un análogo exacto en coma flotante. Si lo que desea es llegar lo más cerca posible, algo como esto puede hacer el truco:

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

dudo de este segundo ejemplo es lo que estás buscando, pero lo incluí para la integridad. Si necesita representar sus números de esta manera internamente, y no solo en la salida, considere usar un fixed-point representation en su lugar.

+0

El redondeo parece funcionar bien, pero por ejemplo redondeando 45.569346543; es 45.599998 .... o 45.5 con * 1.0f ... Estoy más cerca de pensar, necesito leer el piso y el cielo nuevamente. gracias chicos. –

+0

Viene de imprecisión en coma flotante, cambié al doble, funciona muy bien. Gracias. –

+0

Solo para reiterar el comentario de cierre de Matt J, que no estoy seguro que hayas absorbido: 45.6 no se puede representar exactamente en CUALQUIER formato de punto flotante binario, por lo que no es lo que se está almacenando, incluso cuando utilizas el doble. Si su programa ahora está imprimiendo "45.6" es porque las rutinas de salida lo están redondeando. – Spike0xff

1
#include <math.h> 

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

No olvides vincular con -lm. Ver también ceil(), floor() y trunc().

+0

ese redondo al entero más cercano ... no es lo que él pidió. –

+0

eso es correcto, me adelanté a mí mismo. Elegí la respuesta de Eduard. –

27

Claro, puedes usar roundf(). Si desea redondear a un decimal, entonces se podría hacer algo como: roundf(10 * x)/10

+1

Bueno, todos los demás ignoraron el hecho de que el asker no pidió redondear al entero más cercano. Cabe señalar que debido a la imprecisión en el punto flotante. Al imprimir, es probable que vea "45.59999" dado el ejemplo. –

+0

Una buena solución más general sería: double f (double x, int decimal_points) {int n = pow (10, decimal_points); return roundf (n * x)/n; } –

+0

símbolo externo sin resolver _roundf al que se hace referencia en la función _f ha incluido math.h pero no le gusta roundf() Estoy en VS.NET, ¿se encuentra solo para Linux? –

1

Sólo para generalizar la respuesta de Rob un poco, si estás no hacerlo en la salida, se puede seguir utilizando la misma interfaz con sprintf() .

Creo que hay otra manera de hacerlo. Puede intentar ceil() y floor() para redondear hacia arriba y hacia abajo. Un buen truco es agregar 0.5, por lo que cualquier cosa por encima de 0.5 redondea hacia arriba, pero todo lo que está debajo se redondea hacia abajo. ceil() y floor() solo funcionan en double s though.

EDITAR: También, para flotadores, puede usar truncf() para truncar flotadores. El mismo truco de +0.5 debería funcionar para hacer un redondeo preciso.

+0

Puede usar 'ceilf()' y 'floorf()' y 'roundf()' respectivamente para flotantes. – uchuugaka

+0

"Un buen truco es agregar 0.5", falla en muchos casos: [ver comentario] (http://stackoverflow.com/questions/497018/is-there-a-function-to-round-a-float-in -c-or-do-i-need-to-write-my-own # comment57895810_497037). – chux

1

Hay una función round(), también fround(), que redondeará al entero más cercano expresado como un doble. Pero eso no es lo que quieres.

que tenían el mismo problema y escribió esto:

#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

puede utilizar redonda #define (a) (int) (a + 0,5) como macro así que cuando se escribe redonda (1.6) se vuelve 2 y cada vez que se escribe redonda (1.3) devuélvalo 1.

0

Para de impresión un valor redondeado, @Matt J bien responde a la pregunta.

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

Como la mayoría del punto (FP) flotante es binaria basada, exacta de redondear a un decimal lugar no es posible cuando la respuesta es matemáticamente correcto x.1, x.2, ....

Para convertir el número FP en más cercano0.1 es otro asunto.

Desbordamiento: Enfoques que la primera escala por 10 (o 100, 1000, etc.) pueden desbordarse para la gran x.

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

doble redondeo: Adición 0.5f y luego usando floorf(x*10.0f + 0.5f)/10.0 devuelve el resultado incorrecto cuando la suma intermedia x*10.0f + 0.5f rondas hasta un nuevo entero.

// 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 a int tiene el problema obvio cuando float x es mucho mayor que INT_MAX.


Usando roundf() y la familia, disponible en <math.h> es el mejor enfoque.

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

Para evitar el uso de double, sólo tiene que comprobar si el número debe redondeo.

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