7
votes

C # ispowerof fonction

J'ai la fonction suivante:

isPowerOf(16807, 5)


2 commentaires

Lien obligatoire vers Ce que chaque scientifique informatique doit connaître sur l'arithmétique de points flottants


Tout le monde va suggérer de meilleures comparaisons de points flottants, mais imo la racine du problème est l'algorithme ici.


4 Réponses :


6
votes

Essayez d'utiliser un petit epsilon pour des erreurs d'arrondi: xxx

Comme le suggéra Harold, il sera préférable de tourner au cas où A se trouve légèrement plus petit que le valeur entière, comme 3.99999: xxx


5 commentaires

@Guydavid: c'est à cause des erreurs d'arrondi, le nombre que vous avez obtenu n'est pas 7, mais c'est 7h000000001 ou quelque chose comme ça


@Guy David Essayez: console.writeline ((int) a);


Et si le résultat de Math.Pow est désactivé de plus de 0,0001?


@HAROLD: Cela ne devrait pas être, les erreurs arrondies sont généralement à un point constant si vous effectuez un calcul unique.


@Dani peut-être alors, mais cela rompt toujours. Par exemple, pour num = 4 * 4 * 4 pow = 3 , vous obtenez a = 3.9999999999999996 qui est tronqué "/ I>, avec une différence de près d'un. Devrait probablement être un rond plutôt qu'un tronqué.



2
votes

Si vous déboguez le code et vous pouvez ensuite le voir en première comparaison:

isPowerOf(25, 2) 


0 commentaires

2
votes

math.pow fonctionne sur double s, alors les erreurs arrondies entrent en jeu lors de la prise de racines. Si vous souhaitez vérifier que vous avez trouvé un pouvoir exact:

  • Effectuez le math.pow comme actuellement pour extraire la racine
  • rond le résultat à l'entier le plus proche
  • Soulevez cet entier à la puissance fournie et vérifiez que vous obtenez la cible fournie. MATH.POW sera exact pour les numéros de la plage de int lors de la levée des pouvoirs entier

0 commentaires

5
votes

comparaisons qui résolvent la question ont été suggérées, mais ce qui est en réalité le problème ici est que point flottant ne doit pas être impliqué du tout . Vous voulez une réponse exacte à une question impliquant des entiers, pas une approximation des calculs effectués sur des mesures inhérentes inexactes.

Alors, comment cela peut-il être fait?

La première chose qui vous vient à l'esprit est une triche: xxx

Ça fonctionner aussi longtemps que le devinez est moins de 1 de rabais. Mais je ne peux pas garantir que cela fonctionnera toujours pour vos intrants, car cette condition n'est pas toujours remplie.

Voici la chose suivante qui vient à l'esprit: une recherche binaire (la variante où vous recherchez. La limite supérieure d'abord) pour la base dans exponentiatebySquareing (base, puissance) pour laquelle le résultat est le plus proche de num . Si et seulement si la réponse la plus proche est égale à num (et ce sont les deux entiers, cette comparaison est propre), alors num est un Alimentation -ème pouvoir. Sauf si il y a trop de débordement (il ne devrait pas y avoir), cela devrait toujours fonctionner.


1 commentaires

Oui, il y a de bonnes raisons pour lesquelles les entiers et les numéros de points flottants sont des types distincts.