在C语言中保留小数点后N位的四舍五入函数

4

可能是重复问题:
在C语言中将数字保留两位小数

我在c语言中没有找到像这里这样带有签名double round(double d, int digits)的函数。 当我尝试构建时,会出现以下错误:

错误:函数'round'的参数太多

如何在C语言中保留N位小数进行四舍五入?


@melpomene,谢谢,我已经找到了https://dev59.com/pHNA5IYBdhLWcg3wWseK,但我需要获得返回值而不仅仅是打印它。 - testCoder
小数点对于显示是相关的。可以四舍五入到最接近的负十次幂,但是为什么你想要这样做呢? - Pavel Radzivilovsky
2
重新开放投票。所引用的“重复”是一个特殊情况,仅需要保留两位小数进行四舍五入。而本问题涉及到更一般的情况,需要将数字四舍五入到任意位小数。 - andand
4个回答

4

使用递归(某些位数的值会变慢)

#include <math.h>
double my_round(double x, unsigned int digits) {
  if (digits > 0) {
    return my_round(x*10.0, digits-1)/10.0;
  }
  else {
    return round(x);
  }
}

一种可能会更快的方法,但是它依赖于对缓慢的pow函数的单个调用:

#include <math.h>

double my_round(double x, unsigned int digits) {
    double fac = pow(10, digits);
    return round(x*fac)/fac;
}

一个更快的方法是预先计算一个可能的幂的查找表,然后使用它来代替pow
#include <math.h>

double fac[];  // population of this is left as an exercise for the reader

double my_round(double x, unsigned int digits) {
    return round(x*fac[digits])/fac[digits];
}

2
我猜这段代码虽然不是C语言编写的,但是用C++应该可以编译通过。 - Mats Petersson
3
在简单算术就足够的情况下使用递归? - Pavel Radzivilovsky
@PavelRadzivilovsky:这就是为什么在我的原始回复中,我也包括了更有效的方法。 - andand
我会去掉递归。这就像通过月球去药剂师那里一样。 - Pavel Radzivilovsky
我非常惊讶这个在C语言中甚至能够编译通过,更不用说“很好地工作”了。具体来说,我很惊讶编译器没有反对round有两个不同的调用签名,从而导致类型冲突。 - DSM
显示剩余4条评论

1

虽然“answerd”给出了一个不错的答案,但这里有一个适用于任意大数的解决方案:

double round1(double num, int N) {
      ASSERT(N > 0);
      double p10 = pow(10,N);
      return round(num* p10) / p10;
}

当然,如上所述,浮点数没有固定的小数位数,并且如果您调用printf("%8.5f", round1(3.7519, 1));,则不能保证它会打印为3.70000。这是与IT相关的内容。

0

这是一个(非常)简单的函数,

double round1(double num, int N) {
      int temp=(int) num*pow(10,N); 
      double roundedN= temp/pow(10,N);
      return roundedN;
}

这不是四舍五入,而是截断。此外,pow是一项昂贵的操作,请存储结果而不是两次调用它。 - Henry
也许我做错了什么,但我已经反复测试过了,它还是不起作用。 - testCoder
@Henry,对于整数幂的pow函数可以高效地实现(具有O(log n)的复杂度)。因此在这种情况下它是很便宜的。 - Artem Sobolev
@Barmaley.exe,你说得对,但这仍然比O(1)的赋值要多。 - Henry

0

在C标准中,这样的函数并不存在。不过,你可以自己编写一个。

#include <math.h>

/* Round `n` with `c` digits after decimal point. */

double nround (double n, unsigned int c)
{
    double marge = pow (10, c);
    double up    = n * marge;
    double ret   = round (up) / marge;

    return ret;
}

请参考上面关于浮点数“小数点”的评论。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接