Monday, December 1, 2008

MinGW to MSVC -- the case of rint()


I have recently been working on shifting a project over from compiling with the MinGW implementation of the GNU C++ compiler to the Microsoft Visual C++ (MSVC) compiler. The most glaring difference is the lack of the rint() function in MSVC. rint(x) takes a double, x, and returns the double value of the closest integer to x. Being a lazy bum I opened the math.h file for MinGW to copy the rint() function to a global win32 compatibility header. Unfortunately, it is written using an assembly instruction and a bunch of macros. Not wanting to copy the macros over, I did the next lazy thing and used Google.

More unfortunately for me, I copied a version of rint() that was not compatible with the implementation in MinGW. I had:

double rint(double x)
{
     return floor(x < 0.0 ? x - 0.5 : x + 0.5);
}

It turns out, that this is wrong as -1.5 should be rounded to -1.0 and not -2.0. After wasting a few hours debugging, I finally realised it should be the much simpler:

double rint(double x)
{
     return floor(x + 0.5);
}

So much for being a lazy bum...

2 comments:

Anonymous said...

i thought
-1.5 -> -2.0
-0.5 -> -0.0
0.5 -> 0.0
1.5 -> 2.0
etc, i.e. round to nearest integer and to nearest even for ties (though technically it depends on the GPU's current rounding mode)

sorry for answering a two-year old post, found this accidentally searching for MSVC rint

Devil said...

I am not sure about GPU. The code was for CPU and I doubt rint() had a rounding scheme as in your example.