Existe uma função para arredondar um float em C ou que eu preciso para escrever a minha própria?
-
20-08-2019 - |
Pergunta
Existe uma função para arredondar um float em C ou eu preciso escrever meu próprio?
flutuador conver = 45.
59 2346543;
Gostaria de arredondar o valor real de uma casa decimal, conver = 45. 6 .
Solução
Como Rob mencionado, você provavelmente só quero print o flutuador 1 casa decimal. Neste caso, você pode fazer algo como o seguinte:
#include <stdio.h>
#include <stdlib.h>
int main()
{
float conver = 45.592346543;
printf("conver is %0.1f\n",conver);
return 0;
}
Se você quiser realmente arredondar o valor armazenado, que é um pouco mais complicado. Por um lado, a sua representação de uma casa decimal raramente têm um análogo exato em ponto flutuante. Se você só quer ficar o mais próximo possível, algo como isso poderia fazer o truque:
#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;
}
Eu duvido que este segundo exemplo é o que você está procurando, mas eu incluí-lo por completo. Se você exigem representando os números desta forma internamente, e não apenas na saída, considere usar um fixo representação de ponto vez.
Outras dicas
Claro, você pode usar roundf () . Se você quiser rodada para uma casa decimal, então você poderia fazer algo como: roundf(10 * x) / 10
#include <math.h>
double round(double x);
float roundf(float x);
Não se esqueça de ligação com -lm. Veja também ceil (), floor () e trunc ().
Apenas generalizar a resposta de Rob um pouco, se você estiver não fazê-lo na saída, você ainda pode usar a mesma interface com sprintf()
.
Eu acho que não há outra maneira de fazê-lo, no entanto. Você pode tentar ceil()
e floor()
para cima rodada e para baixo. Um bom truque é adicionar 0,5, então qualquer coisa mais de 0,5 rodadas para cima, mas nada sob ele arredonda para baixo. ceil()
e floor()
único trabalho em double
s embora.
EDIT: Além disso, para floats, você pode usar truncf()
para carros alegóricos truncamento. O mesmo +0.5 truque deve trabalhar para fazer o arredondamento preciso.
Há uma função round()
, também fround()
, que volta para o número inteiro mais próximo, expresso em dupla. Mas isso não é o que você quer.
Eu tive o mesmo problema e escreveu o seguinte:
#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;
}
Para print um valor arredondado, @ Matt J bem responde à pergunta.
float x = 45.592346543;
printf("%0.1f\n", x); // 45.6
ponto Como a maioria flutuante (FP) é binário com base, exata ??em> arredondamento a um decimal lugar não é possível quando a resposta matematicamente correta é x.1, x.2, ...
.
Para converter o número FP ao mais próximo 0.1
é outra questão.
x
float round_tenth1(float x) {
x = x * 10.0f;
...
}
Duplo arredondamento :. Adicionando 0.5f e em seguida, usando floorf(x*10.0f + 0.5f)/10.0
retorna o resultado errado quando os intermediários soma x*10.0f + 0.5f
rodadas até um novo inteiro
// 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;
}
Fundição para int
tem o problema óbvio quando float x
é muito maior do que INT_MAX
.
Usando roundf()
e familiar, disponível em <math.h>
é a melhor abordagem.
float round_tenthA(float x) {
double x10 = 10.0 * x;
return (float) (round(x10)/10.0);
}
Para evitar o uso double
, simplesmente testar se o número precisa de arredondamento.
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;
}
Você pode usar #define rodada (a) (int) (a + 0,5) como macro Assim, sempre que você escreve rodada (1,6) retorna 2 e sempre que você escrever round (1.3) que retornar 1.