เป็นวิธีที่มีประสิทธิภาพในการค้นหาทศนิยมซ้ำอะไร


24

ฉันกำลังพยายามที่จะหาขั้นตอนวิธีการที่มีประสิทธิภาพใน Java เพื่อหาสิ่งที่เป็นส่วนหนึ่งของการทำซ้ำทศนิยมสองจำนวนเต็มaและที่ba/b

เช่น. 5/7 = 0.714258 714258 ....

ขณะนี้ฉันรู้วิธีการแบ่งแบบยาวเท่านั้น


2
คุณมี = 5 และ b = 7 และคุณสามารถคำนวณ a / b ในจุดลอยตัวได้ง่ายพอ แต่สิ่งที่คุณอยากรู้คือมันซ้ำหลังจากทศนิยม 6 ตำแหน่ง?
Sparr

คำตอบ:


10

ฉันเชื่อว่ามีสองวิธีทั่วไปที่นี่คุณสามารถ "บังคับเดรัจฉาน" มองหาสายซ้ำที่ยาวที่สุดหรือคุณสามารถแก้มันเป็นปัญหาของทฤษฎีจำนวน

เป็นเวลานานแล้วที่ฉันได้พบกับปัญหานี้ แต่กรณีพิเศษ (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 (mod n) (Glaisher 1878, Lehmer 1941) จำนวนหลักในส่วนที่ซ้ำกันของการขยายทศนิยมของจำนวนตรรกยะสามารถพบได้โดยตรงจากลำดับการคูณของตัวส่วน

ขณะนี้ทฤษฎีจำนวนของฉันค่อนข้างสนิมดังนั้นสิ่งที่ดีที่สุดที่ฉันสามารถทำได้คือชี้ให้คุณไปในทิศทางนั้น


8

ขอและคุณกำลังพยายามที่จะคิดออกเป็นส่วนหนึ่งของการทำซ้ำ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 ถึงอินฟินิตี้และหยุดทันทีที่หารdn * (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ด้วย


1
คำตอบนี้ดูเหมือนถูกต้อง วิธีการที่จะขึ้นอยู่กับต่อไปนี้ "กฎ" 0.123123... = 123/999 0.714258714258... = 714258/999999 (=5/7)ฯลฯ
มาจาก

4
มันล้มเหลวในกรณีเช่น 1/6 หรือ 5/12: \
razpeitia

1
@razpeitia ฉันได้ทำสิ่งที่คล้ายกัน แต่ทำงานในทุกกรณี (รวมถึงการหารจำนวนเต็ม) เช็คเอาต์: codepad.org/hKboFPd2
Tigran Saluev

ฉันใช้งานจาวาสคริปต์ที่คล้ายกับ @ TigranSaluev's ที่github.com/Macil/cycle-division
Macil

2

ส่วนยาว : /

เปลี่ยนผลลัพธ์ให้เป็นสตริงจากนั้นใช้อัลกอริทึมนี้กับมัน ใช้ BigDecimal ถ้าสตริงของคุณมีความยาวไม่เพียงพอกับประเภทสามัญ


4
"เปลี่ยนเป็นสตริง" อาจต้องมีการคำนวณความแม่นยำโดยพลการและสตริงที่ยาวมากในการคำนวณสองส่วนของส่วนที่ซ้ำกันของสตริง (และคุณรู้ได้อย่างไรว่าเมื่อใดที่จะหยุดการคำนวณ? 121212312121231212123 ... จะเป็นปัญหา)
Sparr

@Sparr ความยาวของการทำซ้ำมักจะเล็กกว่าตัวหารเสมอ

@MichaelT ฉันไม่ทราบว่า หากเป็นจริงความแม่นยำจะไม่ "แม่นยำ" แต่สามารถสูงได้ตามอำเภอใจทั้งนี้ขึ้นอยู่กับตัวส่วน
Sparr

@Sparr math.stackexchange.com/questions/298844/…แม้ว่าฉันจะพบทุกสิ่ง 2 / ชื่อเรื่อง /recurring+ decimalอ่านได้มากขึ้น

ฉันไม่คิดว่าอัลกอริทึมที่คุณเชื่อมโยงจะทำงานโดยไม่มีการดัดแปลง มันรวมการทำซ้ำที่ทับซ้อนกันและค้นหาทั่วทั้งสตริง เช่นสตริงย่อยซ้ำที่ยาวที่สุดใน "Banana" คือ "ana"
Web_Designer
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.