# A generic question about Rounding function

## Recommended Posts

JohnsonGPS    109
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 on other sites
Koshmaar    989
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):

/* 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 functionsINTORFLOAT ftoibiasp = {((23 + 127) << 23)};INTORFLOAT ftoibiasn = {((23 + 127) << 23) + (1 << 22)};INTORFLOAT ftmp; // ------------------------------------------------- // ------------------------------------------------- start FloatToIntPositiveSC :: 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 on other sites
JohnBolton    1372
#2 is better because both functions return the same results (at least in the normal cases) and #2 is much simpler.

##### Share on other sites
Troll    246
Quote:
 Original post by KoshmaarIMHO 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 on other sites
Koshmaar    989
Thx Troll, one learns all of his life :-)