2009-03-12 6 views
4

J'ai rencontré un problème avec _controlfp_s (Visual Studio 2008), ou je l'ai compris. Je pensais que le premier paramètre out renvoyait les indicateurs de contrôle avant que les changements des autres paramètres soient appliqués. Il semble qu'il renvoie les drapeaux après le changement.Il est possible qu'un bug dans _controlfp_s ne rétablisse pas correctement le mot de contrôle

Alors, je pensais que la bonne façon de l'utiliser était comme ça:

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

Malheureusement je dois faire:

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

Ai-je raté quelque chose? Cela semble assez stupide d'avoir à faire ça. J'ai signalé cela à MS qui a dit qu'ils ne pouvaient pas le comprendre et j'ai suggéré de fournir une vidéo montrant le problème. Oui en effet.

Brad

+2

A _video_? C'est riche. –

+0

J'ai éclaté de rire à la partie vidéo. Le +1 est en partie pour cela, haha. Aussi, oui, cela semble stupide, peut-être pour des raisons de performance. Peut-être que _controlfp_s ne modifie pas le premier param if mask! = 0, et vous pouvez passer la même référence. Ça vaut le coup je suppose – zildjohn01

+0

Eh bien, si vous n'aimez pas le faire de cette façon, vous pouvez toujours le faire moins facilement en écrivant un assemblage en ligne. –

Répondre

3

Selon MSDN:

Si la valeur de masque est égale à 0, _controlfp_s obtient le mot de commande en virgule flottante. Si le masque est différent de zéro, une nouvelle valeur est définie pour le mot de contrôle: Pour tout bit sur (égal à 1) dans le masque , le bit correspondant dans new est utilisé pour mettre à jour le mot de contrôle. En d'autres mots, fpcntrl = ((fpcntrl & ~ masque) | (nouveau masque &)) où fpcntrl est le mot de contrôle en virgule flottante.

(Souligné par l'auteur) Ainsi, la manière de stocker de manière fiable le mot de commande en cours est la deuxième méthode que vous avez écrit (celui que vous avez déjà trouvé travaillé). Si vous modifiez le mot de contrôle, alors vous ne passerez pas 0 pour le masque, et par la documentation de la fonction, il ne récupérera pas le mot de contrôle actuel.

+1

Le fait est que MSDN ne décrit pas ce que renvoie ce paramètre lorsque le masque est différent de zéro. Il est facile de supposer qu'il renvoie la valeur d'origine et mon premier exemple devrait fonctionner. N'importe quel code de portage de l'ancien controlfp pourrait facilement être piqué par ceci et ne même pas le réaliser. –

+0

controlfp() fonctionne de la même manière. Si vous l'utilisez pour modifier la valeur du mot de contrôle, la valeur de retour est le mot de contrôle modifié; seulement en ne le modifiant pas (masque == 0) pouvez-vous récupérer une valeur non modifiée. – Shog9

+0

Vous avez raison - j'avais complètement mal compris cette fonction. –

0

Donc, il semble que ce soit par nature - ce qui est juste stupide. Quand voudriez-vous connaître le mot de contrôle après l'avoir modifié? Pourtant, vous avez presque toujours perdu l'ancien mot de contrôle, vous pouvez donc le remettre. Cela vous oblige simplement à faire un appel supplémentaire parce que quelqu'un ne pensait pas à la conception de la fonction.

J'ai maintenant passés à cette approche:

_controlfp_s(&uiOldCW, _CW_DEFAULT, 0xfffff); 
Questions connexes