İki tamsayı ave bnerede yinelenen ondalık bölümünü bulmak için Java etkin bir algoritma bulmaya çalışıyorum a/b.
Örneğin. 5/7 = 0.714258 714258 ....
Şu anda sadece uzun bölümleme yöntemini biliyorum.
İki tamsayı ave bnerede yinelenen ondalık bölümünü bulmak için Java etkin bir algoritma bulmaya çalışıyorum a/b.
Örneğin. 5/7 = 0.714258 714258 ....
Şu anda sadece uzun bölümleme yöntemini biliyorum.
Yanıtlar:
Burada iki genel yaklaşım olduğuna inanıyorum, esasen en uzun yinelenen dize için "kaba kuvvet" arayabilir veya sayı teorisi sorunu olarak çözebilirsiniz.
Bu sorunla karşılaştığımdan bu yana çok zaman geçti, ancak özel bir durum (1 / n) Proje Euler'de 26. sırada, bu nedenle bu belirli ad için etkili çözümler arayarak daha fazla bilgi bulabilirsiniz. Bir arama bizi Eli Bendersky'nin web sitesine götürür ve çözümünü açıklar . İşte Mathworld'ün Ondalık Açılımlar sayfasındaki teorinin bir kısmı :
Herhangi bir
m/nnormal olmayan kesir periyodiktir ve en fazla rakam uzunluğunda olan,lambda(n)bağımsız bir süreye sahiptir . Eğer o zaman periyodu, 10 aralarında asal olduğu bir bir bölen bir ve en fazla sahip basamağı, totient işlevidir. 10'un çarpımsal sırası olduğu ortaya çıkıyor (mod ) (Glaisher 1878, Lehmer 1941). Bir rasyonel sayının ondalık genişlemesinin tekrarlayan bölümündeki hane sayısı doğrudan paydasının çarpım sırasından da bulunabilir.mn-1nlambda(n)m/nphi(n)phi(n)philambda(n)n
Sayı teorim şu anda biraz paslı, bu yüzden yapabileceğimin en iyisi sizi bu yöne işaret etmektir.
İzin verin n < d, ve yinelenen kısmını anlamaya çalışıyorsunuz n/d. pTekrarlayan kısımdaki hane sayısı olsun : o zaman n/d = R * 10^(-p) + R * 10^(-2p) + ... = R * ((10^-p)^1 + (10^-p)^2 + ...). Parantezli kısım, eşittir geometrik bir seridir 1/(10^p - 1).
Yani n / d = R / (10^p - 1). Almak için yeniden düzenleyin R = n * (10^p - 1) / d. R'yi bulmak için p1'den sonsuza kadar döngü yapın ve deşit olarak bölündüklerinde durun n * (10^p - 1).
İşte Python'da bir uygulama:
def f(n, d):
x = n * 9
z = x
k = 1
while z % d:
z = z * 10 + x
k += 1
return k, z / d
( kyinelenen dizinin uzunluğunu izler, böylece 1/9 ile 1/99 arasında ayrım yapabilirsiniz)
Bu uygulamanın (ironik olarak), ondalık genişlemenin sonlu olması durumunda sonsuza kadar döngüye girdiğini, ancak sonsuz olması durumunda sona erdiğini unutmayın! Yine de, bu durumu kontrol edebilirsiniz çünkü 2 veya 5 olmayan n/dtüm asal faktörler dde mevcutsa , yalnızca sınırlı bir ondalık gösterime sahip olacaktır n.
0.123123... = 123/999 0.714258714258... = 714258/999999 (=5/7)vs
Uzun bölüm? : /
Sonucu bir dizgeye çevirin ve bu algoritmayı ona uygulayın. Dizeniz sıradan türlerle yeterince uzun değilse, BigDecimal kullanın.