Question

Après une heure d'essayer de trouver un bug dans mon code, je l'ai finalement trouvé la raison. Je tentais d'ajouter un très petit flotteur à 1f, mais rien ne se passait. Tout en essayant de comprendre pourquoi j'ai trouvé que l'ajout de ce petit flotteur 0f a parfaitement fonctionné.

Pourquoi est-ce qui se passe? Est-ce que cela a à voir avec les « ordres de grandeur »? Y at-il solution à ce problème?

Merci d'avance.

Edit:

Le passage à double précision ou décimal est pas une option pour le moment.

Était-ce utile?

La solution

Parce que la précision d'un simple précision (32 bits) de la valeur en virgule flottante est de l'ordre de 7 chiffres après la virgule. Ce qui signifie que la valeur que vous ajoutez est essentiellement zéro, au moins lorsqu'il est ajouté à 1. Cependant, la valeur elle-même, peut facilement stockée dans un flotteur puisque l'exposant est faible dans ce cas. Mais pour ajouter avec succès à vous 1 devez utiliser l'exposant du plus grand nombre ... et puis les chiffres après les zéros disparaissent dans l'arrondissement.

Vous pouvez utiliser double si vous avez besoin de plus de précision. Côté performance cela ne devrait pas faire une différence sur le matériel d'aujourd'hui et de la mémoire est souvent pas aussi limité que vous devez penser à chaque variable.

EDIT: Comme vous avez déclaré que l'utilisation double n'est pas une option que vous pouvez utiliser sommation Kahan , comme akuhn a souligné dans un commentaire.

Une autre option pourrait consister à effectuer des calculs intermédiaires en double précision et par la suite exprimés à float à nouveau. Cela n'aider, cependant, quand il y a quelques opérations que le simple ajout d'un très petit nombre à un plus grand.

Autres conseils

Cela se produit probablement parce que le nombre de chiffres de précision dans un flotteur est constant, mais l'exposant peut évidemment varier.

Cela signifie que même si vous pouvez ajouter votre petit nombre à 0, vous ne pouvez pas attendre à l'ajouter à un nombre qui a un exposant différent de 0, car il ne veut pas suffisamment de chiffres de précision à gauche.

Vous devriez lire Ce que tout informaticien doit savoir sur Arithmétique à virgule flottante .

On dirait qu'il a quelque chose à voir avec une précision en virgule flottante. Si je devais vous, j'utiliser un autre type, comme decimal. Cela devrait corriger les erreurs de précision.

Avec float, vous obtenez seulement un précision d'environ sept chiffres . Ainsi, votre number'll arrondi en 1F. Si vous souhaitez stocker ce nombre, utilisez plutôt double

http://msdn.microsoft.com/en-us/library /ayazw934.aspx

En plus de la réponse acceptée: Si vous avez besoin de résumer beaucoup petit nombre et quelques plus grands, vous devez utiliser Kahan Summation .

Si la performance est un problème (parce que vous ne pouvez pas utiliser double), puis mise à l'échelle binaire / fixe le point peut être une option. floats sont stockés sous forme d'entiers, mais mis à l'échelle par un grand nombre (par exemple, 2 ^ 16). arithmétique intermédiaire est fait avec des opérations entières (relativement rapide). La réponse finale peut être reconverti en virgule flottante à la fin, en divisant par le facteur d'échelle.

Ceci est souvent fait si le processeur cible ne dispose pas d'une unité matérielle à virgule flottante.

Vous utilisez le suffixe f sur vos littéraux, qui fera ces flotteurs au lieu de doubles. Donc, votre très petit flotteur va disparaître dans le plus grand flotteur.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top