Estoy tratando de encontrar un algoritmo eficiente en Java para encontrar la parte decimal repetitiva de dos enteros a
y b
dónde a/b
.
p.ej. 5/7 = 0.714258 714258 ....
Actualmente solo conozco el método de división larga.
algorithms
math
Jun Hao
fuente
fuente
Respuestas:
Creo que hay dos enfoques generales aquí, esencialmente puedes "fuerza bruta" buscar la cadena de repetición más larga, o puedes resolverlo como un problema de teoría de números.
Ha pasado mucho tiempo desde que me encontré con este problema, pero un caso especial (1 / n) es el problema # 26 en el Proyecto Euler, por lo que puede encontrar más información buscando soluciones eficientes para ese nombre específico. Una búsqueda nos lleva al sitio web de Eli Bendersky, donde explica su solución . Aquí hay algo de la teoría de la página Expansiones decimales de Mathworld :
Mi teoría de los números está un poco oxidada en este momento, así que lo mejor que puedo hacer es señalarlo en esa dirección.
fuente
Deja
n < d
, y estás tratando de descubrir la parte que se repiten/d
. Dejep
ser el número de dígitos en la parte que se repite: entoncesn/d = R * 10^(-p) + R * 10^(-2p) + ... = R * ((10^-p)^1 + (10^-p)^2 + ...)
. La parte entre corchetes es una serie geométrica, igual a1/(10^p - 1)
.Por lo tanto
n / d = R / (10^p - 1)
. Reorganizar para obtenerR = n * (10^p - 1) / d
. Para encontrar R, repitap
de 1 a infinito y pare tan pronto como sed
divida de manera uniformen * (10^p - 1)
.Aquí hay una implementación en Python:
(
k
realiza un seguimiento de la longitud de la secuencia de repetición, por lo que puede distinguir entre 1/9 y 1/99, por ejemplo)Tenga en cuenta que esta implementación (irónicamente) se repite para siempre si la expansión decimal es finita, ¡pero termina si es infinita! Sin embargo, puede verificar este caso, ya
n/d
que solo tendrá una representación decimal finita si todos los factores primosd
que no son 2 o 5 también están presentesn
.fuente
0.123123... = 123/999
0.714258714258... = 714258/999999 (=5/7)
etc.¿División larga? : /
Convierta el resultado en una cadena y luego aplique este algoritmo . Use BigDecimal si su cadena no es lo suficientemente larga con los tipos normales.
fuente