Ceci est probablement une question pour un expert x86 FPU:arrondi à virgule flottante lorsque tronquer
Je suis en train d'écrire une fonction qui génère une valeur de virgule flottante aléatoire dans l'intervalle [min, max]. Le problème est que mon algorithme de générateur (le Twister Mersenne à virgule flottante, si vous êtes curieux) ne renvoie que des valeurs dans la plage [1,2] - ie, je veux une limite supérieure inclusive, mais ma valeur générée "source" est à partir d'une limite supérieure exclusive. La capture ici est que le générateur sous-jacent renvoie un double de 8 octets, mais je veux seulement un flottant de 4 octets, et j'utilise le mode d'arrondi FPU par défaut de Nearest. Ce que je veux savoir est si la troncature elle-même dans ce cas résultera dans ma valeur de retour en incluant le maximum quand la valeur 80-bit interne de FPU est suffisamment proche, ou si je devrais augmenter le significand de ma valeur maximum avant de le multiplier par l'intermédiaire aléatoire dans [1,2), ou si je devrais changer de mode FPU. Ou bien d'autres idées, bien sûr.
Voici le code que je suis actuellement en utilisant, et je vérifiaient que 1.0f décide de 0x3f800000:
float MersenneFloat(float min, float max)
{
//genrand returns a double in [1,2)
const float random = (float)genrand_close1_open2();
//return in desired range
return min + (random - 1.0f) * (max - min);
}
Si cela fait une différence, cela doit travailler sur Win32 MSVC++ et Linux gcc. En outre, l'utilisation de toutes les versions des optimisations SSE changera-t-elle la réponse?
Editer: La réponse est oui, la troncature dans ce cas du double au flottant est suffisante pour que le résultat inclue max. Voir la réponse de Crashworks pour plus.
Maintenant, pourquoi n'ai-je pas pensé à lancer ce test parmi les autres que j'ai courus :) J'ai découvert qu'avec la troncature, le 1.99999 arrondira à 2 avec et sans/arch: SSE2. Merci! –
Heureux d'aider - J'étais curieux de savoir quel serait le résultat du test moi-même. – Crashworks