5 votos

Encontrando los dígitos iniciales en cualquier número

Estoy un poco perplejo por esta (presumiblemente muy simple) problema.

Simplemente, estoy tratando de encontrar el primer dígito(s) en cualquier número (relacionados con la pregunta). Aquí hay algunos buenos código de python (a partir de esta pregunta):

import math

def first_n_digits(num, n):
    # where n is the number of leading digits of interest
    return num // 10 ** (int(math.log(num, 10)) - n + 1)

Esto funciona bien para la mayoría de los números, por ejemplo:

>>> first_n_digits(123456, 1)
1
>>> first_n_digits(123456, 2)
12
>>> first_n_digits(123456, 3)
123
>>> first_n_digits(123456, 4)
1234
>>> first_n_digits(123456, 5)
12345
>>> first_n_digits(123456, 6)
123456

El problema es que esto no funciona para num=1000 y n=1.

first_n_digits(1000, 1)
10

Este problema no aparece cuando num = 10,100,10000,100000. Sólo num = 1000.

¿Cómo se puede lidiar con este caso extremo? No he encontrado ninguna a los demás hasta el momento. Espero que haya alguna solución muy simple que he pasado por alto.

7voto

Mees de Vries Puntos 165

El problema es simplemente errores de redondeo. La operación int cuando se aplica a una positiva (?) flotador, se redondea el número hacia abajo hasta el entero más próximo. Esto funciona bien si se pretende que la salida de math.log es exacto, pero no lo es:

>>> math.log(1000, 10)
2.9999999999999996
>>> int(math.log(1000, 10))
2

Hay maneras de solucionar este problema, por ejemplo, mediante la prueba de lo que sucede si usted calcula 10 a la potencia de la salida de este cálculo, pero, más en general, la dificultad es que nunca se puede garantizar que las operaciones de punto flotante será exacta, simplemente porque es imposible para representar todos los posibles números reales en un equipo.

De hecho, el Python el camino para resolver su problema es el totalmente robusto función (al menos para los enteros positivos, y asumiendo n toma un valor razonable)

def first_n_digits(num, n):
    return int(str(num)[:n])

2voto

gandalf61 Puntos 486

Documentación de Python para las matemáticas.registro dice

Con dos argumentos, devolver el logaritmo de x a la base, que se calcula como log(x)/log(base).

Así que es posible que $\text{math.log}(1000,10)$ es devolver un valor muy ligeramente menos de 3 debido a errores de redondeo, y cuando se aplica int a esto, se consigue $2$. Trate de evaluar $\text{int}(\text{math.log}(1000,10))$ a ver si esto se evalúa a $2$ o $3$. (Veo Mees de Vries ya ha hecho esta prueba).

Hay una alternativa de la función en el módulo de matemáticas llamado de matemáticas.log10:

Devolver el logaritmo en base 10 de x. Esto suele ser más preciso que el de log(x, 10).

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X