Sign in to follow this  
JohnsonGPS

A generic question about Rounding function

Recommended Posts

I am defining a rounding function in my program, and there is no spec on it, so basically I am at large. For example, I can either round -4.5 to -4 or -5, but I would like to know which one conforms to the programming convention better. I guess I have left the campus for too long and forgot what the professor said at the class. Here are the codes: 1) static double Rounding (double dx) {return (dx>0.0)?(floor(dx+0.5)):(ceil(dx-0.5));} 2) static double Rounding (double dx) {return (floor(dx+0.5));} Could anybody let me know which one is better? BTW, I feel it is pretty dangerous to compare the double variable with a constant, and it will bring in some ambiguity somehow. Does anybody know a better method to find out a double variable positive or negative? Thanks. Johnson

Share this post


Link to post
Share on other sites
IMHO rounding, as it name suggests, should work like normal mathematical rounding do: if fractional part is < .5, round to lower value, otherwise - round to higher value. This way, everyone will intuitively know what's this function supposed to do.

However, as for the exact implementations, I suggest to use theese, they're much faster than normal casting (and probably much faster than your versions):


Header:



/* They all _round_ to nearest integer, not throw away values after decimal point (like normal casting do).

ie.

0.1 -> 0
0.2 -> 0
0.3 -> 0
0.4 -> 0
0.5 -> 1
0.6 -> 1
0.7 -> 1
0.8 -> 1
0.9 -> 1
1.0 -> 1

*/


ulint FloatToIntPositive(float _f); //!< 5x times faster than casting
slint FloatToIntNegative(float _f); //!< 5x times faster than casting
slint FloatToInt(float _f); //!< 2x times faster than casting





Basically, if you know that certain value must be positive, use FloatToIntPositive, else - FloatToIntNegative. If you don't know what the sign is, use FloatToInt.
Btw, probably you also should inline them.


Source:


// ------------------------------------------------- used by some math functions

INTORFLOAT ftoibiasp = {((23 + 127) << 23)};
INTORFLOAT ftoibiasn = {((23 + 127) << 23) + (1 << 22)};
INTORFLOAT ftmp;

// -------------------------------------------------

// ------------------------------------------------- start FloatToIntPositive

SC :: ulint SC :: FloatToIntPositive(float _f)
{
ftmp.f = _f;
ftmp.f += ftoibiasp.f;
ftmp.i -= ftoibiasp.i;
return ftmp.i;
}

// ------------------------------------------------- end FloatToIntPositive

// ------------------------------------------------- start FloatToIntNegative

SC :: slint SC :: FloatToIntNegative(float _f)
{
ftmp.f = _f;
ftmp.f += ftoibiasn.f;
ftmp.i -= ftoibiasn.i;
return ftmp.i;
}

// ------------------------------------------------- end FloatToIntNegative

// ------------------------------------------------- start FloatToInt

SC :: slint SC :: FloatToInt(float _f)
{
return ( (_f < 0) ? (FloatToIntNegative(_f)) : (FloatToIntPositive(_f)) );
}
// ------------------------------------------------- end FloatToInt



Share this post


Link to post
Share on other sites
Quote:
Original post by Koshmaar
IMHO rounding, as it name suggests, should work like normal mathematical rounding do: if fractional part is < .5, round to lower value, otherwise - round to higher value. This way, everyone will intuitively know what's this function supposed to do.


"Normal" rounding isn't necessarily the best choice. There are alternative rounding schemes, such as bankers' rounding, that try to address the shortcomings of normal rounding. Microsoft has a good page on the topic:

http://support.microsoft.com/default.aspx?scid=kb;en-us;196652

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this