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

发布于 2024-07-13 04:01:15 字数 183 浏览 7 评论 0原文

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

浮点转换器 = 45.592346543;

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

Is there a function to round a float in C or do I need to write my own?

float conver = 45.592346543;

I would like to round the actual value to one decimal place, conver = 45.6.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

浮世清欢 2024-07-20 04:01:15

正如 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;
}

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

As Rob mentioned, you probably just want to print the float to 1 decimal place. In this case, you can do something like the following:

#include <stdio.h>
#include <stdlib.h>

int main()
{
  float conver = 45.592346543;
  printf("conver is %0.1f\n",conver);
  return 0;
}

If you want to actually round the stored value, that's a little more complicated. For one, your one-decimal-place representation will rarely have an exact analog in floating-point. If you just want to get as close as possible, something like this might do the trick:

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

I doubt this second example is what you're looking for, but I included it for completeness. If you do require representing your numbers in this way internally, and not just on output, consider using a fixed-point representation instead.

娇女薄笑 2024-07-20 04:01:15

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

Sure, you can use roundf(). If you want to round to one decimal, then you could do something like: roundf(10 * x) / 10

风柔一江水 2024-07-20 04:01:15
#include <math.h>

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

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

#include <math.h>

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

Don't forget to link with -lm. See also ceil(), floor() and trunc().

带刺的爱情 2024-07-20 04:01:15

只是为了稍微概括一下 Rob 的答案,如果您在输出上执行此操作,您仍然可以使用与 sprintf() 相同的接口。

不过,我认为还有另一种方法可以做到这一点。 您可以尝试 ceil()floor() 进行向上和向下舍入。 一个不错的技巧是加上 0.5,因此超过 0.5 的任何内容都会向上舍入,而低于 0.5 的任何内容都会向下舍入。 不过,ceil()floor() 仅适用于 double

编辑:此外,对于浮点数,您可以使用 truncf() 来截断浮点数。 同样的 +0.5 技巧应该可以实现精确的舍入。

Just to generalize Rob's answer a little, if you're not doing it on output, you can still use the same interface with sprintf().

I think there is another way to do it, though. You can try ceil() and floor() to round up and down. A nice trick is to add 0.5, so anything over 0.5 rounds up but anything under it rounds down. ceil() and floor() only work on doubles though.

EDIT: Also, for floats, you can use truncf() to truncate floats. The same +0.5 trick should work to do accurate rounding.

ゃ人海孤独症 2024-07-20 04:01:15

打印一个四舍五入的值,@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;
}

float x远大于INT_MAX时,转换int会出现明显的问题。


使用 中提供的 roundf() 及其族是最好的方法。

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

To print a rounded value, @Matt J well answers the question.

float x = 45.592346543;
printf("%0.1f\n", x);  // 45.6

As most floating point (FP) is binary based, exact rounding to one decimal place is not possible when the mathematically correct answer is x.1, x.2, ....

To convert the FP number to the nearest 0.1 is another matter.

Overflow: Approaches that first scale by 10 (or 100, 1000, etc) may overflow for large x.

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

Double rounding: Adding 0.5f and then using floorf(x*10.0f + 0.5f)/10.0 returns the wrong result when the intermediate sum x*10.0f + 0.5f rounds up to a new integer.

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

Casting to int has the obvious problem when float x is much greater than INT_MAX.


Using roundf() and family, available in <math.h> is the best approach.

float round_tenthA(float x) {
  double x10 = 10.0 * x;
  return (float) (round(x10)/10.0);
}

To avoid using double, simply test if the number needs rounding.

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;
}
浅笑依然 2024-07-20 04:01:15

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

you can use #define round(a) (int) (a+0.5) as macro
so whenever you write round(1.6) it returns 2 and whenever you write round(1.3) it return 1.

青芜 2024-07-20 04:01:15

有一个 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;
} 

There is a round() function, also fround(), which will round to the nearest integer expressed as a double. But that is not what you want.

I had the same problem and wrote this:

#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;
} 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文