我需要一个简单的浮点舍入函数,这样:
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++库中,或者它是否丢失了??
当前回答
将浮点值四舍五入小数“n”位的最佳方法如下,在O(1)时间内:-
我们必须将值四舍五入3位,即n=3。所以,
float a=47.8732355;
printf("%.3f",a);
其他回答
你可以四舍五入到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)的另一个原因。
Boost中还实现了某种类型的舍入:
#include <iostream>
#include <boost/numeric/conversion/converter.hpp>
template<typename T, typename S> T round2(const S& x) {
typedef boost::numeric::conversion_traits<T, S> Traits;
typedef boost::numeric::def_overflow_handler OverflowHandler;
typedef boost::numeric::RoundEven<typename Traits::source_type> Rounder;
typedef boost::numeric::converter<T, S, Traits, OverflowHandler, Rounder> Converter;
return Converter::convert(x);
}
int main() {
std::cout << round2<int, double>(0.1) << ' ' << round2<int, double>(-0.1) << ' ' << round2<int, double>(-0.9) << std::endl;
}
注意,这仅在执行到整数的转换时有效。
我是这样做的:
#include <cmath.h>
using namespace std;
double roundh(double number, int place){
/* place = decimal point. Putting in 0 will make it round to whole
number. putting in 1 will round to the
tenths digit.
*/
number *= 10^place;
int istack = (int)floor(number);
int out = number-istack;
if (out < 0.5){
floor(number);
number /= 10^place;
return number;
}
if (out > 0.4) {
ceil(number);
number /= 10^place;
return number;
}
}
如果你最终想要将round()函数的双输出转换为int型,那么这个问题的可接受的解决方案将如下所示:
int roundint(double r) {
return (int)((r > 0.0) ? floor(r + 0.5) : ceil(r - 0.5));
}
当传入均匀随机值时,在我的机器上大约为8.88 ns。
据我所知,下面的功能是等效的,但在我的机器上是2.48 ns,具有显著的性能优势:
int roundint (double r) {
int tmp = static_cast<int> (r);
tmp += (r-tmp>=.5) - (r-tmp<=-.5);
return tmp;
}
性能更好的原因之一是跳过了分支。