Comment pourrais-je réussir à faire en math.ceil
sorte qu'un nombre soit attribué à la prochaine puissance la plus élevée de 10?
# 0.04 -> 0.1
# 0.7 -> 1
# 1.1 -> 10
# 90 -> 100
# ...
Ma solution actuelle est un dictionnaire qui vérifie la plage du numéro d'entrée, mais il est codé en dur et je préférerais une solution à une ligne. Peut-être qu'il me manque une astuce mathématique simple ou une fonction numpy correspondante ici?
10
haut, cela aura besoin de quelque chose avec par exemplelog10
.Réponses:
Vous pouvez utiliser
math.ceil
avecmath.log10
pour cela:log10(n)
vous donne la solutionx
qui vous satisfait10 ** x == n
, donc si vous arrondissezx
cela vous donne l'exposant pour la prochaine puissance la plus élevée de 10.Notez que pour une valeur
n
oùx
est déjà un entier, la "prochaine puissance la plus élevée de 10" seran
:la source
10 ** math.ceil(math.log10(1)) == 1
, qui n'est pas "la prochaine puissance la plus élevée"Votre problème est sous-spécifié, vous devez prendre du recul et poser quelques questions.
Dans une autre réponse, il a été proposé de prendre le logarithme, puis d'arrondir (fonction plafond), puis d'exposer.
Malheureusement, cela souffre d'erreurs d'arrondi. Tout d'abord, n est converti à partir de n'importe quel type de données qu'il se trouve avoir en un nombre à virgule flottante double précision, introduisant potentiellement des erreurs d'arrondi, puis le logarithme est calculé, introduisant potentiellement plus d'erreurs d'arrondi à la fois dans ses calculs internes et dans son résultat.
En tant que tel, il ne m'a pas fallu longtemps pour trouver un exemple où il a donné un résultat incorrect.
Il est également théoriquement possible qu'il échoue dans l'autre sens, bien que cela semble beaucoup plus difficile à provoquer.
Donc, pour une solution robuste pour les flottants et les entiers, nous devons supposer que la valeur de notre logarithme n'est qu'approximative, et nous devons donc tester quelques possibilités. Quelque chose dans le sens de
Je crois que ce code devrait donner des résultats corrects pour tous les arguments dans une gamme sensible de magnitudes réelles. Il se cassera pour de très petits ou très grands nombres de types non entiers et non flottants en raison de problèmes de conversion en virgule flottante. Cas spéciaux Python arguments entiers à la fonction log10 dans le but d'empêcher le débordement, mais toujours avec un entier suffisamment massif, il peut être possible de forcer des résultats incorrects en raison d'erreurs d'arrondi.
Pour tester les deux implémentations, j'ai utilisé le programme de test suivant.
Cela trouve beaucoup d'échecs dans l'implémentation naïve, mais aucun dans l'implémentation améliorée.
la source
round
au lieu demath.ceil
? Cela introduira de nombreux cas inutiles lorsque celar < n
est vrai et qu'il doit donc effectuer un travail supplémentaire.Il semble que vous souhaitiez plutôt la prochaine puissance la plus basse de 10 ... Voici un moyen d'utiliser des mathématiques pures et pas de journal, mais de récursivité.
la source
Quelque chose comme ça peut-être? C'est juste sur le dessus de ma tête, mais cela a fonctionné lorsque j'ai essayé quelques chiffres dans le terminal.
la source
Regarde ça!
Ce code basé sur le principe du pouvoir de dix en
len( str( int( float_number ) ) )
.Il y a 4 cas:
int( i ) > 1
.Float
nombre - converti enint
, puis chaîne àstr()
partir de celui-ci, nous donnera unstring
aveclength
lequel nous cherchons exactement. Donc, première partie, pour l'entréei > 1.0
- c'est dix10
en puissance de cette longueur.i > 1.0
eti > 0.1
<=> c'est10
et1
respectivement.i < 0.1
: Ici, dix doivent avoir une puissance négative. Pour obtenir le premier élément non nul après une virgule, j'ai utilisé une telle construction("%.100f" % i ).replace('.','').index( k )
, où k est exécuté sur un[1:10]
intervalle. Ensuite, prenez le minimum de liste de résultats. Et diminuer d'une unité, c'est d'abord zéro, qui doit être compté. De plus, est ici standard de Pythonindex()
peut se bloquer, si elle ne trouvera pas au moins l' un des élément non nul d'[1:10]
intervalle, qui est la raison pour laquelle à la fin je dois « filtrer » la liste par occurrence:if str( j ) in "%.100f" % i
. En outre, pour obtenir une précision plus profonde -%.100f
peuvent être prises différemment.la source