C 中是否有对浮点数进行四舍五入的函数,或者我需要编写自己的函数吗?

问题描述 投票:0回答:7

C 中是否有对浮点数进行四舍五入的函数,还是我需要编写自己的函数?

浮点转换器 = 45.592346543;

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

c floating-point rounding
7个回答
34
投票

正如 Rob 提到的,您可能只想打印浮点到小数点后一位。 在这种情况下,您可以执行以下操作:

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

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


33
投票

当然,你可以使用roundf()。如果您想四舍五入到一位小数,那么您可以执行以下操作:

roundf(10 * x) / 10


3
投票
#include <math.h>

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

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


1
投票

只是为了概括一下 Rob 的答案,如果您在输出上执行此操作,您仍然可以使用与

sprintf()
相同的界面。

不过,我认为还有另一种方法可以做到这一点。您可以尝试使用

ceil()
floor()
进行向上和向下舍入。一个不错的技巧是加上 0.5,因此超过 0.5 的任何内容都会向上舍入,而低于 0.5 的任何内容都会向下舍入。但
ceil()
floor()
仅适用于
double

编辑:此外,对于浮点数,您可以使用

truncf()
来截断浮点数。同样的 +0.5 技巧应该可以实现精确的舍入。


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

双重舍入:当中间和floorf(x*10.0f + 0.5f)/10.0

向上舍入为新整数时,添加 0.5f 然后使用 
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.0f/FLT_EPSILON; if (fabsf(x) < limit) { return roundf(x*10.0f)/10.0f; } return x; }
    

0
投票
您可以使用 #define round(a) (int) (a+0.5) 作为宏 因此,每当您写入 round(1.6) 时,它都会返回 2,每当您写入 round(1.3) 时,它都会返回 1。


-1
投票
有一个

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; }
    
© www.soinside.com 2019 - 2024. All rights reserved.