Question

Je suis en train de faire un peu d'arithmétique à virgule flottante et ayant des problèmes de précision. La valeur résultante est différente sur deux machines pour la même entrée. J'ai lu le message @ Pourquoi ne puis-je multiplierai un flotteur aussi lire d'autres documents sur le web et il est entendu que ça a à voir avec la représentation binaire de la virgule flottante et sur la machine epsilon. Cependant, je voulais vérifier s'il y a un moyen de résoudre ce problème / Certains autour de travail pour l'arithmétique en virgule flottante en C ++ ?? Je suis en train de convertir un flotteur à court non signé pour le stockage et je retransforme en cas de besoin. Cependant, quand je reconvertir à court non signé, la précision (6 points décimaux) reste correcte sur une machine, mais échoue sur l'autre.

//convert FLOAT to short

unsigned short sConst = 0xFFFF;

unsigned short shortValue = (unsigned short)(floatValue * sConst);

//Convert SHORT to FLOAT

float floatValue = ((float)shortValue / sConst);
Était-ce utile?

La solution

A short doit être d'au moins 16 bits, et dans beaucoup d'implémentations qui est exactement ce qu'il est. Un unsigned short 16 bits tiendra des valeurs de 0 à 65535. Cela signifie qu'un court ne tiendra pas cinq chiffres complets de précision, et certainement pas six. Si vous voulez six chiffres, vous avez besoin de 20 bits.

Par conséquent, toute perte de précision est probablement due au fait que vous essayez d'emballer six chiffres de précision en quelque chose de moins de cinq chiffres. Il n'y a pas de solution à cela, autre que l'utilisation d'un type intégral qui prend probablement autant de stockage comme float.

Je ne sais pas pourquoi il semble travailler sur un système donné. Avez-vous utilisé les mêmes chiffres sur les deux? At-on utiliser un système à virgule flottante plus, et qui a donné par hasard les résultats que vous attendiez sur les échantillons que vous avez essayé? Est-ce en utilisant peut-être un short plus grand que l'autre?

Autres conseils

Si vous voulez utiliser des types à virgule flottante natif, le meilleur que vous pouvez faire est d'affirmer que les valeurs de sortie par votre programme ne diffèrent pas trop d'un ensemble de valeurs de référence.

La définition précise de « trop » dépend entièrement de votre application. Par exemple, si vous calculez a + b sur différentes plates-formes, vous devriez trouver les deux résultats se situer dans la précision de la machine de l'autre. D'autre part, si vous faites quelque chose de plus compliqué, comme l'inversion de la matrice, les résultats les plus fluctueront probablement plus de précision de la machine. Déterminer avec précision à quel point vous pouvez vous attendre que les résultats soient à l'autre est un processus très subtil et compliqué. À moins que vous savez exactement ce que vous faites, il est probablement plus sûr (et Saner) pour déterminer la quantité de précision dont vous avez besoin en aval dans votre application et vérifier que le résultat est suffisamment précis.

Pour avoir une idée sur la façon de calculer l'erreur relative entre deux valeurs à virgule flottante avec vigueur, voir cette réponse et le guide à virgule flottante lié dans celui-ci:

flottant fonctions de comparaison de points pour C #

Au lieu d'utiliser 0xFFFF utiliser la moitié de celui-ci, à savoir 32768 pour la conversion. 32768 (Ox8000) a une représentation binaire de 1000000000000000 alors OxFFFF a une représentation binaire de représentation binaire de 1111111111111111. Ox8000 implique clairement, les opérations de multiplication et Divsion lors de la conversion (à court (ou) lors de la conversion de retour à flotteur) ne changera pas les valeurs de précision après zéro. Pour une conversion de côté, mais OxFFFF est préférable, car elle conduit à des résultats plus précis.

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