est-ce correct? C'est le meilleur que j'ai réussi après une quantité de temps embarrassante sur le problème: p> L'application est un jeu simple que j'ai pris sur la propriété d'un programmeur précédent. Curieusement, il a choisi de mélanger des flotteurs et des doubles impertinemment, à la fois dans les variables de membre et d'argumentation, il y a donc beaucoup de coulée implicite et explicite inutile de monter et descendre. P> Les coordonnées du joueur sont au double x, y (Le joueur est supposé être un point). Il y a un carreau float_size, et le monde est un certain nombre de rangées et de colonnes de carreaux, ainsi que de la manipulation générique hors limites. En supposant que la coordonnée (x, y) est dans les limites, j'essaie de comprendre quels tuiles l'utilisateur est en basée sur X (pour obtenir une colonne) ou Y (pour obtenir la ligne). C'est comme, programmeur 101. P> wlog, au début, je faisais juste puis j'ai découvert que, par exemple, Mais maintenant je ne suis pas sûr de ce que les autres bugs se cachent dans cette approche ou quelle serait la meilleure approche. p> (il peut ne pas sembler comme une si gros problème si l'utilisateur est juste sur la cuspide d'être d'une rangée d'une rangée ou d'une autre, et nous nous sommes accidentellement arrondis dans le mauvais; mais le vrai problème est dans le code, où Nous voyons des changements de signe inattendu (+, -, 0). Par exemple, une partie du code suppose que si l'utilisateur est sur la tuile à (R, C), il est alors que le point est en réalité contenue par cette géométrie de carrelage. Quand ce n'est pas , nous obtenons des choses comme des distances négatives lorsque seuls les non négatifs sont attendus, etc., et cela provoque des affirmations de tirer et de tirer des boucles à briser et ainsi de suite.) p> p> col = (int) (x / tuile_size) code>. Mais comme je l'ai découvert, par exemple, .5 / .1f <5, et donc (int) (. 5 / .1f) == 4 code>, la mauvaise réponse. Cela a conduit à ce qui précède si la déclaration et la formulation du problème. P> (int) (- 9,999999747378752e-5 / .1f) == 0 code> , qui m'a conduit à appeler math.floor code> d'abord. p>
3 Réponses :
Je pense que vous devriez essayer de résoudre le problème de la racine (.1f trop loin de .1), c'est-à-dire de tourner en tuile_size en un double ou d'utiliser des flotteurs de manière systématique partout. Sinon, vous pourriez avoir des problèmes similaires causés par des erreurs d'arrondi minimales tout au long du code. La fonction candidate_answer est un piratage pour contourner un problème qui ne devrait pas exister en premier lieu.
P.s. P>
Pour ce problème particulier, vous voudrez peut-être simplement trouver une formule plus robuste, c'est-à-dire que cela n'est pas sensible aux erreurs d'arrondi minimales dans une seule direction. Essayez de placer le joueur au centre de son champ au lieu de le bord de la tuile où il peut facilement tomber dans des erreurs d'arrondi: p> (idéalement, le minimal_step_size / 2 faites déjà partie de x au lieu d'être ajouté ici) p> p>
Je suis d'accord avec la correction du problème de la racine, mais je pense qu'un meilleur moyen de le faire serait de passer à une représentation intégrale à point fixe. Avec Tile_Size 256 et tous les coordonnées des entiers signés 32 bits, vous avez beaucoup de résolution au sein de chaque carreau et une zone de la carte de 16 millions de tuiles.
D'accord, mais cela pourrait être un refactoring beaucoup plus vaste, et le point fixe a son propre ensemble de problèmes (par exemple, faire preuve de dépassement des multiplications, peut être plus difficile à déboguer) ....
Utiliser Double Tout ce qui semble être le moyen d'y aller. Cependant, cela ne résout pas le problème de la racine: l'utilisation de l'arithmétique de point flottant est toujours liée à des erreurs d'arrondies.
Lorsque vous utilisez un point flottant arithmétique, il est toujours bon de travailler avec un epsilon (E) de précision: P> < p> Si vous souhaitez vérifier si x est égal à y (où une variable est un type de point flottant), utilisez le motif suivant: p>
Jetez-le dans un epsilon et maintenant vous avez deux problèmes au lieu d'un: quel est le bon epsilon universel? Et vous ne montrez pas comment cela aiderait le problème initial réel. Si vous faites cela, vous pouvez simplement utiliser des numéros de points fixes, car il tue essentiellement l'aspect ponctuel flottant des nombres de points flottants. Considérons 0.000001 et 0.000002: la différence est inférieure à votre epsilon, mais un chiffre est deux fois l'autre. Je pense ici, le problème de la racine positionnant un joueur de la taille d'un point situé au bord de son champ au lieu du milieu de celui-ci, ce qui rend tout enclin à arrondir des erreurs.
si f code> et g code> est à la fois positif (ils semblent être), votre méthode peut être réduite à un seul calcul simple: i <= g/f
Avez-vous lu la question du tout? "Au début, je faisais juste Col = (int) (x / tuile_size). Mais comme je l'ai découvert, par exemple, 0,5 / .1f <5, et donc (. 5 / .1f) == 4, le mauvaise réponse. Cela a conduit à ce qui précède si la déclaration et la formulation du problème. "
i * g ou i * g <= f code>?<=, et mis à jour; Merci.