Возможная ошибка в _controlfp_s может неправильно восстановить контрольное слово - PullRequest
4 голосов
/ 12 марта 2009

Я сталкивался с проблемой _controlfp_s (Visual Studio 2008) или с моим пониманием. Я думал, что первый выходной параметр вернул контрольные флаги до применения изменений других параметров. Кажется, он возвращает флаги после изменения.

Итак, я подумал, что правильный способ его использования был следующим:

// 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);

К сожалению, мне нужно сделать это:

// 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);

Я что-то пропустил? Кажется, довольно глупо это делать.

Кстати: я сообщил об этом MS, которая сказала, что они не могут понять это, и предложила предоставить видео, показывающее проблему. Да, верно.

Бред

Ответы [ 2 ]

3 голосов
/ 12 марта 2009

Согласно MSDN :

Если значение для маски равно 0 , _controlfp_s получает управляющее слово с плавающей точкой. Если маска ненулевая, устанавливается новое значение для контрольного слова: Для любого бита, который включен (равен 1) в маска, соответствующий бит в новом используется для обновления контрольного слова. В другими словами, fpcntrl = ((fpcntrl & ~ маска) | (новый и маска)) где fpcntrl управляющее слово с плавающей запятой.

(выделено мое) Таким образом, способ надежного хранения текущего контрольного слова - это второй метод, который вы написали (тот, который вы уже нашли, сработал). Если вы изменяете управляющее слово, вы не будете передавать 0 для маски и в соответствии с документацией функции не получит текущее управляющее слово.

0 голосов
/ 13 марта 2009

Так что похоже, что это может быть задумано - что просто глупо.

Когда вы захотите узнать контрольное слово после его изменения? Тем не менее, вы почти всегда не хотите использовать старое контрольное слово, чтобы вы могли вернуть его обратно.

Это просто заставляет вас сделать дополнительный вызов, потому что кто-то не думал, когда разрабатывал функцию.

Итак, я перешел на этот подход:

_controlfp_s(&uiOldCW, _CW_DEFAULT, 0xfffff);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...