0
votes

LEETCode 231: Problème de déterminer si un nombre donné est le pouvoir de 2

Je veux trouver si un numéro donné est un Puissance de deux dans une manière mathématique, pas em> avec une approche bitwise. Voici mon code:

private static double logBaseTwo(final double x) {
    return Math.log(x) / Math.log(2);
}

private static double roundToNearestHundredThousandth(final double x) {
    return Math.round(x * 100000.0) / 100000.0;
}

private static boolean isInteger(final double x) {
    return (int)(Math.ceil(x)) == (int)(Math.floor(x));
}

public static boolean isPowerOfTwo(final int n) {
    return isInteger(roundToNearestHundredThousandth(logBaseTwo(n)));
}


5 commentaires

J'espère que vous réalisez que l'utilisation d'une approche mathématique est une approche mathématique. Ils suggèrent que vous suggérez est trop complexe et a du mal à travailler sur des ordinateurs.


@RUAKH Il est faux de modifier la question de sorte qu'il invalide une réponse. S'il vous plaît mettre l'opérateur du TrinGal.


@Nomadmaker: La question concernait pourquoi le code ne fonctionne pas. Comme RzwitserLoot a souligné, l'opérateur ternaire n'a pas affecté le comportement du code; Donc, ce n'est pas vraiment pertinent pour la question.


@ruakh il confond la compréhension de la réponse. Il aurait dû être laissé dans ou un commentaire mis dans la question indiquant que le code d'origine (...) a été remplacé par ce code (...).


@Nomadmaker: J'ai maintenant édité cette réponse pour clarifier ce que cela fait référence.


5 Réponses :


1
votes

C'est vraiment horriblement mauvais code, et je n'ai aucune idée de ce que vous essayez de faire. Vous semblez essayer de vérifier si le journal BASE 2 de n est un entier. Au lieu de cela, j'écrirais une boucle: xxx


0 commentaires

1
votes

La solution semble plus compliquée qu'elle ne devrait l'être. Je ne reçois pas les pièces 100000d code> - semble potentiellement causer des problèmes lors de la conversion au plafond.

Ceci est la solution simple qui fonctionne pour tous les cas: P>

public static boolean isPowerOfTwo(int n) {
    return Math.ceil(Math.log(n)/Math.log(2)) == Math.floor(Math.log(n)/Math.log(2));
}


2 commentaires

+1. L'arrondi au cent le plus proche est exactement le problème: log₂ 524287 ≈ 18.999997 est arrondi à 19,0, ce qui est un entier. Donc, d'un sens, le code de l'OP arrondi 524287 au 524288, qui est une puissance de deux. (Et, au fait, bienvenue dans le débordement de la pile!)


En fait, désolé, cette réponse n'est pas correcte: ce code renvoie mal false pour 536870912 (au moins sur mon système), car le résultat du point flottant est 29.000000000000004 au lieu de 29 .



1
votes

Les doubles et les flotteurs ont respectivement une précision de 64 bits et 32 ​​bits. Cela signifie qu'ils peuvent contenir au plus grand nombre de 18446744073709551616 numéros uniques. C'est beaucoup de chiffres, mais pas une quantité infinie d'entre eux. À un moment donné (en fait, ce point survient à 2 ^ 52), le «écart» entre tous les 2 chiffres faisant partie des utilisateurs de 18446744073709551616 représentables devient supérieur à 1.000. Des règles similaires s'appliquent aux petits nombres. Math.log utilise-t-il double mathématiques basées.

Personnellement, les INT sont similaires limités. Ils peuvent contenir jusqu'à 4294967296 numéros différents. Pour INTS, c'est beaucoup plus simple: les intens peuvent tenir à partir de -2147483648 jusqu'à 2147483647. Si vous essayez d'ajouter 1 à 2147483647, vous obtenez -2147483648 (en silence en silence). Il est tout à fait possible que vous rencontrez cela avec une tentative de convertir un nombre aussi grand (votre double fois 10000D) à un int d'abord.

Notez que ? TRUE: FALSE (comme dans la version originale de la question) est littéralement complètement inutile. La chose à gauche du point d'interrogation doit être un booléen et les booléens sont déjà vrais ou faux, c'est leur nature.

Voir les autres réponses pour des approches plus simples de ce problème. Bien que, bien sûr, la solution la plus simple consiste simplement à compter simplement les bits dans le nombre. Si c'est précisément 1 bit, c'est une puissance de 2. Si c'est 0 bits, eh bien, vous me dites si vous considérez "0" une puissance de 2 :)


0 commentaires

1
votes

À l'origine, j'ai eu un problème en utilisant math.log code> dans mes calculs. Je suis passé à math.log10 code> et le problème est parti. Bien que mathématiquement, tout logbe code> de base B devrait fonctionner, la nature des calculs de points flottants peut être imprévisible.

Essayez ceci. p> xxx pré>

Si vous préférez utiliser des journaux, vous pouvez le faire de cette façon. P>

public static boolean isPowerOfTwo(int n) {
   return n > 0 && (Math.log10(n)/Math.log10(2))%1 == 0;
}



1 commentaires

C'était mon erreur et je suis incertain de la façon dont je l'ai négligé. Utiliser Math.Log n'a pas éliminé l'erreur de mathématique, donc je suis passé à Math.Log10 et cela a fonctionné. Cela me dérange toujours parce que l'utilisation du journal de n'importe quelle base du numérateur et du dénominateur doit fonctionner. Mais c'est des mathématiques et nous travaillons avec IEEE754, de sorte que même l'utilisation du CEIL et des méthodes de plancher n'élimineraient pas la minuscule erreur du calcul.



3
votes

Votre code échoue car vous aurez peut-être besoin de plus de précision que vous permettant de capturer la différence entre les journaux de Big_Number et Big_Number + 1

Le chemin Bitwise est vraiment meilleur, mais si vous voulez vraiment utiliser uniquement des opérations "mathy" , alors le meilleur que vous puissiez faire est probablement: xxx

Cette solution ne nécessite aucune précision super-fine et fonctionnera bien pour tous les InTS positifs. < / p>


0 commentaires