ฉันกำลังพยายามที่จะหาขั้นตอนวิธีการที่มีประสิทธิภาพใน Java เพื่อหาสิ่งที่เป็นส่วนหนึ่งของการทำซ้ำทศนิยมสองจำนวนเต็มa
และที่b
a/b
เช่น. 5/7 = 0.714258 714258 ....
ขณะนี้ฉันรู้วิธีการแบ่งแบบยาวเท่านั้น
ฉันกำลังพยายามที่จะหาขั้นตอนวิธีการที่มีประสิทธิภาพใน Java เพื่อหาสิ่งที่เป็นส่วนหนึ่งของการทำซ้ำทศนิยมสองจำนวนเต็มa
และที่b
a/b
เช่น. 5/7 = 0.714258 714258 ....
ขณะนี้ฉันรู้วิธีการแบ่งแบบยาวเท่านั้น
คำตอบ:
ฉันเชื่อว่ามีสองวิธีทั่วไปที่นี่คุณสามารถ "บังคับเดรัจฉาน" มองหาสายซ้ำที่ยาวที่สุดหรือคุณสามารถแก้มันเป็นปัญหาของทฤษฎีจำนวน
เป็นเวลานานแล้วที่ฉันได้พบกับปัญหานี้ แต่กรณีพิเศษ (1 / n) เป็นปัญหาที่ # 26 ใน Project Euler ดังนั้นคุณอาจหาข้อมูลเพิ่มเติมได้ด้วยการค้นหาวิธีแก้ปัญหาที่มีประสิทธิภาพสำหรับชื่อเฉพาะนั้น ค้นหาหนึ่งนำเราไปยังเว็บไซต์ของ Eli Bendersky ที่เขาอธิบายถึงวิธีการแก้ปัญหาของเขา นี่คือทฤษฎีบางส่วนจากหน้าส่วนขยายทศนิยมของ Mathworld :
เศษส่วนที่ไม่สม่ำเสมอใด ๆ
m/n
นั้นเป็นคาบและมีระยะเวลาlambda(n)
อิสระm
ซึ่งมีความn-1
ยาวไม่เกินหลัก หากn
ค่อนข้างสำคัญถึง 10 ดังนั้นระยะเวลาlambda(n)
ของm/n
คือตัวหารของphi(n)
และมีที่phi(n)
หลักมากที่สุดซึ่งphi
เป็นฟังก์ชั่น Totient ปรากฎว่าlambda(n)
เป็นคำสั่งคูณของ 10 (modn
) (Glaisher 1878, Lehmer 1941) จำนวนหลักในส่วนที่ซ้ำกันของการขยายทศนิยมของจำนวนตรรกยะสามารถพบได้โดยตรงจากลำดับการคูณของตัวส่วน
ขณะนี้ทฤษฎีจำนวนของฉันค่อนข้างสนิมดังนั้นสิ่งที่ดีที่สุดที่ฉันสามารถทำได้คือชี้ให้คุณไปในทิศทางนั้น
ขอและคุณกำลังพยายามที่จะคิดออกเป็นส่วนหนึ่งของการทำซ้ำn < d
n/d
อนุญาตเป็นจำนวนของตัวเลขในส่วนการทำซ้ำแล้วp
ส่วนในวงเล็บเป็นชุดเรขาคณิตเท่ากับn/d = R * 10^(-p) + R * 10^(-2p) + ... = R * ((10^-p)^1 + (10^-p)^2 + ...)
1/(10^p - 1)
n / d = R / (10^p - 1)
ดังนั้น R = n * (10^p - 1) / d
จัดเรียงที่จะได้รับ เพื่อหา R, วงp
จาก 1 ถึงอินฟินิตี้และหยุดทันทีที่หารd
n * (10^p - 1)
นี่คือการใช้งานใน Python:
def f(n, d):
x = n * 9
z = x
k = 1
while z % d:
z = z * 10 + x
k += 1
return k, z / d
( k
ติดตามความยาวของลำดับการทำซ้ำดังนั้นคุณสามารถแยกความแตกต่างระหว่าง 1/9 ถึง 1/99 เป็นต้น)
โปรดทราบว่าการใช้งานนี้ (แดกดัน) ลูปตลอดไปหากการขยายทศนิยมเป็นจำนวน จำกัด แต่ยุติถ้ามันไม่มีที่สิ้นสุด! อย่างไรก็ตามคุณสามารถตรวจสอบกรณีนี้ได้เนื่องจากn/d
จะมีการแสดงทศนิยมแบบ จำกัด เฉพาะหากปัจจัยหลักทั้งหมดd
ที่ไม่ใช่ 2 หรือ 5 นั้นมีอยู่n
ด้วย
0.123123... = 123/999
0.714258714258... = 714258/999999 (=5/7)
ฯลฯ
ส่วนยาว : /
เปลี่ยนผลลัพธ์ให้เป็นสตริงจากนั้นใช้อัลกอริทึมนี้กับมัน ใช้ BigDecimal ถ้าสตริงของคุณมีความยาวไม่เพียงพอกับประเภทสามัญ