¿Cómo me las arreglaría para math.ceil
que un número se asigne a la siguiente potencia más alta de 10?
# 0.04 -> 0.1
# 0.7 -> 1
# 1.1 -> 10
# 90 -> 100
# ...
Mi solución actual es un diccionario que verifica el rango del número de entrada, pero está codificado y preferiría una solución de una línea. ¿Tal vez me estoy perdiendo un simple truco matemático o una función numpy correspondiente aquí?
10
arriba, esto necesitará algo con, por ejemplolog10
.Respuestas:
Puedes usar
math.ceil
conmath.log10
para hacer esto:log10(n)
te da la soluciónx
que satisface10 ** x == n
, por lo que si la redondeasx
te da el exponente para la próxima potencia más alta de 10.Tenga en cuenta que para un valor
n
dondex
ya es un entero, la "próxima potencia más alta de 10" serán
:fuente
10 ** math.ceil(math.log10(1)) == 1
, que no es "la próxima potencia más alta"Su problema está subespecificado, debe retroceder y hacer algunas preguntas.
En otra respuesta, se propuso tomar el logaritmo, luego redondear hacia arriba (función de techo), luego exponer.
Lamentablemente, esto sufre de errores de redondeo. En primer lugar, n se convierte de cualquier tipo de datos que tenga en un número de coma flotante de doble precisión, lo que potencialmente introduce errores de redondeo, luego el logaritmo se calcula y posiblemente introduce más errores de redondeo tanto en sus cálculos internos como en su resultado.
Como tal, no me llevó mucho tiempo encontrar un ejemplo en el que proporcionara un resultado incorrecto.
También es teóricamente posible que falle en la otra dirección, aunque esto parece ser mucho más difícil de provocar.
Entonces, para una solución robusta para flotadores e ints, debemos suponer que el valor de nuestro logaritmo es solo aproximado y, por lo tanto, debemos probar un par de posibilidades. Algo en la línea de
Creo que este código debería dar resultados correctos para todos los argumentos en un rango sensible de magnitudes del mundo real. Se romperá para números muy pequeños o muy grandes de tipos no enteros y de punto flotante debido a problemas al convertirlos en punto flotante. Los argumentos enteros de casos especiales de Python para la función log10 en un intento de evitar el desbordamiento, pero aún con un número entero suficientemente masivo, es posible forzar resultados incorrectos debido a errores de redondeo.
Para probar las dos implementaciones utilicé el siguiente programa de prueba.
Esto encuentra muchas fallas en la implementación ingenua, pero ninguna en la implementación mejorada.
fuente
round
lugar demath.ceil
? Esto introducirá muchos casos innecesarios donder < n
es cierto y, por lo tanto, debe realizar un trabajo adicional.Parece que quieres más bien la próxima potencia más baja de 10 ... Aquí hay una manera de usar matemáticas puras y sin registro, sino recurrencia.
fuente
¿Algo así quizás? Está justo en la parte superior de mi cabeza, pero funcionó cuando probé algunos números en la terminal.
fuente
¡Mira esto!
Este código se basa en el principal del poder de diez
len( str( int( float_number ) ) )
.Hay 4 casos:
int( i ) > 1
.Float
número - convertido aint
, a partir de entonces una cadena astr()
partir de él, nos dará unastring
con lalength
que estamos buscando exactamente. Entonces, la primera parte, para la entradai > 1.0
, es diez10
en potencia de esta longitud.i > 1.0
yi > 0.1
<=> es10
y1
respectivamente.i < 0.1
: Aquí, diez estarán en poder negativo. Para obtener el primer elemento distinto de cero después de la coma, he utilizado dicha construcción("%.100f" % i ).replace('.','').index( k )
, donde k se ejecuta en[1:10]
intervalos. A partir de entonces, tome el mínimo de la lista de resultados. Y disminuir en uno, es el primer cero, que se contará. Además, aquí pitón de normaindex()
puede bloquearse, si no va a encontrar por lo menos uno de no-cero elemento de[1:10]
intervalo, que es lo que al final debo "filtro" lista de ocurrencia:if str( j ) in "%.100f" % i
. Además, para obtener una precisión más profunda,%.100f
puede tomarse diferente.fuente