Подтвердить что ты не робот

Есть ли функция для округления поплавка на C или мне нужно написать собственное?

Есть ли функция для округления поплавка на C или мне нужно написать свой собственный?

float conversion = 45. 59 2346543;

Я хотел бы округлить фактическое значение до одного десятичного знака, конвертировать = 45. 6.

4b9b3361

Ответ 1

Как сказал Роб, вы, вероятно, просто хотите напечатать 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;
}

Я сомневаюсь, что этот второй пример - это то, что вы ищете, но я включил его для полноты. Если вам требуется представлять свои номера таким образом внутренне, а не только на выходе, вместо этого используйте вместо представление с фиксированной точкой.

Ответ 2

Конечно, вы можете использовать roundf(). Если вы хотите округлить до одного десятичного знака, вы можете сделать что-то вроде: roundf(10 * x) / 10

Ответ 3

#include <math.h>

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

Не забудьте связать с -lm. См. Также ceil(), floor() и trunc().

Ответ 4

Просто, чтобы обобщить Роб ответ немного, если вы не делаете это на выходе, вы все равно можете использовать тот же интерфейс с sprintf().

Я думаю, что есть еще один способ сделать это. Вы можете попробовать ceil() и floor() округлить вверх и вниз. Хороший трюк состоит в том, чтобы добавить 0.5, поэтому ничего более 0,5 раундов, но все под ним округляется. ceil() и floor() работают только на double.

EDIT: Кроме того, для float вы можете использовать truncf() для усечения поплавков. Тот же +0,5 трюк должен работать для точного округления.

Ответ 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;
} 

Ответ 6

вы можете использовать #define round (a) (int) (a + 0.5) в качестве макроса  поэтому всякий раз, когда вы пишете раунд (1.6), он возвращает 2, и всякий раз, когда вы пишете раунд (1.3), он возвращает 1.

Ответ 7

Чтобы напечатать округленное значение, @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;
}