views:

253

answers:

2

Hi All,

I've stumbled across either a problem with _controlfp_s (Visual Studio 2008), or my understanding of it. I thought the first out parameter returned the control flags before changes of the other parameters are applied. Seems it returns the flags after the change.

So, I thought the correct way to use it was like this:

// Chop rounding
unsigned int old;
_controlfp_s(&old, _RC_CHOP, _MCW_RC);

// Do chopped math


// Restore
unsigned int unused;
_controlfp_s(&unused, old, _MCW_RC);

Unfortunately I need to do this:

// Save
unsigned int old1;
_controlfp_s(&old1, 0, 0);

// Chop rounding
unsigned int old2;
_controlfp_s(&old2, _RC_CHOP, _MCW_RC);

// Do chopped math


// Restore
unsigned int unused;
_controlfp_s(&unused, old1, _MCW_RC);

Have I missed something? Seems pretty stupid to have to do this.

btw: I've reported this to MS who said they couldn't understand it and suggested I provide a video showing the problem. Yeah right.

Brad

+2  A: 

According to MSDN:

If the value for mask is equal to 0, _controlfp_s gets the floating-point control word. If mask is nonzero, a new value for the control word is set: For any bit that is on (equal to 1) in mask, the corresponding bit in new is used to update the control word. In other words, fpcntrl = ((fpcntrl & ~mask) | (new & mask)) where fpcntrl is the floating-point control word.

(emphasis mine) So the way to reliably store the current control word is the second method you've written (the one you already found worked). If you're modifying the control word, then you won't be passing 0 for the mask, and per the function documentation it will not retrieve the current control word.

Shog9
The point is that MSDN doesn't describe what that out parameter returns when the mask is non-zero. It's easy to assume it returns the original value and my first example should work. Anyone porting code from the old controlfp could easily get stung by this and not even realise it.
cantabilesoftware
controlfp() works the same way. If you use it to modify the value of the control word, the return value is the modified control word; only by not modifying it (mask == 0) can you retrieve an unmodified value.
Shog9
You're right - I'd completely misunderstood this function.
cantabilesoftware
A: 

So it looks like this might be by design - which is just stupid.

When would you ever want to know the control word after you've changed it? Yet you almost always wan't the old control word so you can put it back.

This just forces you to make an extra call because someone wasn't thinking when they designed the function.

So I've now switched to this approach:

_controlfp_s(&uiOldCW, _CW_DEFAULT, 0xfffff);
cantabilesoftware