26

是否有一个函数可以在 C 中舍入一个浮点数,还是我需要自己编写?

浮点转换 = 45. 59 2346543;

我想将实际值四舍五入到小数点后一位, conver = 45. 6

4

7 回答 7

31

当然,您可以使用roundf()。如果你想四舍五入到小数点后,你可以这样做:roundf(10 * x) / 10

于 2009-01-30T20:08:15.807 回答
31

正如 Rob 所提到的,您可能只想将浮点数打印到小数点后 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;
}

我怀疑第二个示例是您要查找的内容,但为了完整起见,我将其包含在内。如果您确实需要在内部以这种方式表示您的数字,而不仅仅是在输出上,请考虑使用定点表示

于 2009-01-30T20:19:19.327 回答
2
#include <math.h>

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

不要忘记与 -lm 链接。另请参见 ceil()、floor() 和 trunc()。

于 2009-01-30T20:07:57.617 回答
1

只是为了概括 Rob 的回答,如果您不在输出上执行此操作,您仍然可以使用与sprintf().

不过,我认为还有另一种方法可以做到这一点。你可以尝试ceil()上下floor()四舍五入。一个很好的技巧是添加 0.5,因此任何超过 0.5 的内容都会向上取整,但低于 0.5 的任何内容都会向下取整。ceil()并且floor()只在doubles 上工作。

编辑:另外,对于浮点数,您可以使用truncf()截断浮点数。相同的 +0.5 技巧应该可以进行精确的舍入。

于 2009-01-30T20:09:00.767 回答
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 等)缩放的方法可能会溢出 large x.

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

双舍入floorf(x*10.0f + 0.5f)/10.0:当中间和向上舍入x*10.0f + 0.5f到一个新整数时,添加 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 xINT_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;
}
于 2016-01-29T17:27:11.797 回答
0

还有一个round()函数,也fround()可以四舍五入到最接近的整数,表示为双精度数。但这不是你想要的。

我有同样的问题并写了这个:

#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;
} 
于 2014-05-22T17:22:53.290 回答
0

你可以使用#define round(a) (int) (a+0.5) 作为宏,所以当你写 round(1.6) 时它返回 2,而当你写 round(1.3) 时它返回 1。

于 2015-04-15T02:57:32.383 回答