我需要一个简单的浮点舍入函数,这样:
double round(double);
round(0.1) = 0
round(-0.1) = 0
round(-0.9) = -1
我可以在math.h中找到ceil()和floor() -但没有round()。
它是否以另一个名字出现在标准c++库中,或者它是否丢失了??
我需要一个简单的浮点舍入函数,这样:
double round(double);
round(0.1) = 0
round(-0.1) = 0
round(-0.9) = -1
我可以在math.h中找到ceil()和floor() -但没有round()。
它是否以另一个名字出现在标准c++库中,或者它是否丢失了??
当前回答
Boost提供了一组简单的舍入函数。
#include <boost/math/special_functions/round.hpp>
double a = boost::math::round(1.5); // Yields 2.0
int b = boost::math::iround(1.5); // Yields 2 as an integer
有关更多信息,请参阅Boost文档。
编辑:从c++ 11开始,有std::round, std::lround和std::llround。
其他回答
Boost提供了一组简单的舍入函数。
#include <boost/math/special_functions/round.hpp>
double a = boost::math::round(1.5); // Yields 2.0
int b = boost::math::iround(1.5); // Yields 2 as an integer
有关更多信息,请参阅Boost文档。
编辑:从c++ 11开始,有std::round, std::lround和std::llround。
编者注:下面的答案提供了一个简单的解决方案,其中包含几个实现缺陷(参见Shafik Yaghmour的答案以获得完整的解释)。注意,c++ 11已经将std::round、std::lround和std::llround作为内置程序。
c++ 98标准库中没有round()。不过你可以自己写。下面是round-half-up的实现:
double round(double d)
{
return floor(d + 0.5);
}
c++ 98标准库中没有循环函数的可能原因是它实际上可以以不同的方式实现。以上是一种常见的方法,但还有其他的方法,如四舍五入到偶数,如果你要做很多四舍五入,这种方法的偏差更小,通常更好;不过实现起来有点复杂。
round_f for ARM with math
static inline float round_f(float value)
{
float rep;
asm volatile ("vrinta.f32 %0,%1" : "=t"(rep) : "t"(value));
return rep;
}
没有数学的ARM的round_f
union f__raw {
struct {
uint32_t massa :23;
uint32_t order :8;
uint32_t sign :1;
};
int32_t i_raw;
float f_raw;
};
float round_f(float value)
{
union f__raw raw;
int32_t exx;
uint32_t ex_mask;
raw.f_raw = value;
exx = raw.order - 126;
if (exx < 0) {
raw.i_raw &= 0x80000000;
} else if (exx < 24) {
ex_mask = 0x00ffffff >> exx;
raw.i_raw += 0x00800000 >> exx;
if (exx == 0) ex_mask >>= 1;
raw.i_raw &= ~ex_mask;
};
return raw.f_raw;
};
你可以四舍五入到n位精度:
double round( double x )
{
const double sd = 1000; //for accuracy to 3 decimal places
return int(x*sd + (x<0? -0.5 : 0.5))/sd;
}
小心地板(x+0.5)。下面是在[2^52,2^53]范围内奇数的情况:
-bash-3.2$ cat >test-round.c <<END
#include <math.h>
#include <stdio.h>
int main() {
double x=5000000000000001.0;
double y=round(x);
double z=floor(x+0.5);
printf(" x =%f\n",x);
printf("round(x) =%f\n",y);
printf("floor(x+0.5)=%f\n",z);
return 0;
}
END
-bash-3.2$ gcc test-round.c
-bash-3.2$ ./a.out
x =5000000000000001.000000
round(x) =5000000000000001.000000
floor(x+0.5)=5000000000000002.000000
这里是http://bugs.squeak.org/view.php?id=7134。使用@konik这样的解决方案。
我自己的健壮版本是这样的:
double round(double x)
{
double truncated,roundedFraction;
double fraction = modf(x, &truncated);
modf(2.0*fraction, &roundedFraction);
return truncated + roundedFraction;
}
这里给出了避免下限(x+0.5)的另一个原因。