c++ rounding of numbers away from zero

笑着哭i 提交于 2020-01-30 04:39:10

问题


Hi i want to round double numbers like this (away from zero) in C++:

  4.2 ---->   5
  5.7 ---->   6
 -7.8 ---->  -8
-34.2 ----> -35

What is the efficient way to do this?


回答1:


inline double myround(double x)
{
  return x < 0 ? floor(x) : ceil(x);
}

As mentioned in the article Huppie cites, this is best expressed as a template that works across all float types

See http://en.cppreference.com/w/cpp/numeric/math/floor and http://en.cppreference.com/w/cpp/numeric/math/floor

or, thanks to Pax, a non-function version:

x = (x < 0) ? floor(x) : ceil(x);



回答2:


There is a nice article about a similar problem on CPlusPlus.com. The easy solution to your problem should be something like this:

double customRound( double value ) const {
   return value < 0 ? floor( value ) : ceil( value );
}

A better solution is the one mentioned in the article, which uses a template:

//--------------------------------------------------------------------------
// symmetric round up
// Bias: away from zero
template <typename FloatType>
FloatType ceil0( const FloatType& value )
{
   FloatType result = std::ceil( std::fabs( value ) );
   return (value < 0.0) ? -result : result;
}



回答3:


The x < 0 ? floor(x) : ceil(x); approach of Ruben Bartelink is good. Yet consider what happens with special cases of x = -0.0, x = NaN.

Rather than have myround(-0.0) potentially return +0.01 and have myround(NaN) return with a changed payload of the NaN, consider the below.

myround_alt(-0.0) returns -0.0.

myround_alt(NaN) more likely returns an unchanged payload NaN. Not-a-number stuff is tricky and not well defined. IAC, it is the myround_alt(-0.0) --> -0.0 I am seeking.

inline double myround_alt(double x) {
  if (x > 0) return ceil(x);
  if (x < 0) return floor(x);
  return x;
}

1IEC 60559 floating-point arithmetic specifies ceil(±0) returns ±0 so this approach not needed with implementations that strictly follow that spec. Yet many C floating point implementation do not follow that (C does not require it) or fail in such comer cases like this.




回答4:


try

 double rounded = _copysign(ceil(abs(x)), x);



回答5:


This will work, and it does not even require math.h, or any libraries. I took a distinct approach to achieve the wanted functionality. Flooring negative numbers and ceiling positive numbers is just one way to do it. It does the same thing as truncating the number, and increasing the absolute value by one, If it is not already an integer. Like this:

inline double InvertedTrunc(double Number) {
    return (Number == (int)Number ? Number : ((int)Number)+(Number < 0 ? -1 : 1)); //casting to int truncates it
} //Though be aware of overflow, not recommended for large numbers

Though something to be aware of is overflow, so this is not recommended for larger numbers.



来源:https://stackoverflow.com/questions/1326510/c-rounding-of-numbers-away-from-zero

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!