Есть ли функция для округления поплавка на C или мне нужно написать свой собственный?
float conversion = 45. 59 2346543;
Я хотел бы округлить фактическое значение до одного десятичного знака, конвертировать = 45. 6.
Есть ли функция для округления поплавка на C или мне нужно написать свой собственный?
float conversion = 45. 59 2346543;
Я хотел бы округлить фактическое значение до одного десятичного знака, конвертировать = 45. 6.
Как сказал Роб, вы, вероятно, просто хотите напечатать float до 1 десятичного разряда. В этом случае вы можете сделать что-то вроде следующего:
#include <stdio.h>
#include <stdlib.h>
int main()
{
float conver = 45.592346543;
printf("conver is %0.1f\n",conver);
return 0;
}
Если вы хотите фактически округлить сохраненное значение, это немного сложнее. Во-первых, ваше одно-десятичное представление редко будет иметь точный аналог в плавающей точке. Если вы просто хотите приблизиться как можно ближе, что-то вроде этого может сделать трюк:
#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;
}
Я сомневаюсь, что этот второй пример - это то, что вы ищете, но я включил его для полноты. Если вам требуется представлять свои номера таким образом внутренне, а не только на выходе, вместо этого используйте вместо представление с фиксированной точкой.
Конечно, вы можете использовать roundf(). Если вы хотите округлить до одного десятичного знака, вы можете сделать что-то вроде: roundf(10 * x) / 10
#include <math.h>
double round(double x);
float roundf(float x);
Не забудьте связать с -lm. См. Также ceil(), floor() и trunc().
Просто, чтобы обобщить Роб ответ немного, если вы не делаете это на выходе, вы все равно можете использовать тот же интерфейс с sprintf()
.
Я думаю, что есть еще один способ сделать это. Вы можете попробовать ceil()
и floor()
округлить вверх и вниз. Хороший трюк состоит в том, чтобы добавить 0.5, поэтому ничего более 0,5 раундов, но все под ним округляется. ceil()
и floor()
работают только на double
.
EDIT: Кроме того, для float вы можете использовать truncf()
для усечения поплавков. Тот же +0,5 трюк должен работать для точного округления.
Существует функция round()
, также fround()
, которая будет округляться до ближайшего целого числа, выраженного как double. Но это не то, что вы хотите.
У меня была та же проблема и написала:
#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;
}
вы можете использовать #define round (a) (int) (a + 0.5) в качестве макроса поэтому всякий раз, когда вы пишете раунд (1.6), он возвращает 2, и всякий раз, когда вы пишете раунд (1.3), он возвращает 1.
Чтобы напечатать округленное значение, @Matt J отвечает на вопрос.
float x = 45.592346543;
printf("%0.1f\n", x); // 45.6
Поскольку большинство чисел с плавающей запятой (FP) основано на двоичном выражении, точное округление до одного десятичного знака невозможно, если математически правильный ответ x.1, x.2, ...
.
Чтобы преобразовать номер FP в ближайший 0.1
, это другое дело.
Переполнение. Подходы к первой шкале на 10 (или 100, 1000 и т.д.) могут переполняться для больших x
.
float round_tenth1(float x) {
x = x * 10.0f;
...
}
Двойное округление: добавление 0.5f, а затем с помощью floorf(x*10.0f + 0.5f)/10.0
возвращает неправильный результат, когда промежуточная сумма x*10.0f + 0.5f
округляется до нового целого.
// 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;
}
Отбрасывание до int
имеет очевидную проблему, когда float x
намного больше INT_MAX
.
Использование roundf()
и семейства, доступное в <math.h>
, является наилучшим подходом.
float round_tenthA(float x) {
double x10 = 10.0 * x;
return (float) (round(x10)/10.0);
}
Чтобы избежать использования double
, просто проверьте, требуется ли округление округления.
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;
}