2009-08-22 12 views
10

क्या निम्नलिखित चीजों को जानने के लिए कोई एल्गोरिदम है?दोहराव decimals का पता लगाने के लिए एल्गोरिदम?

  1. यदि विभाजन का परिणाम दोहराना दशमलव (बाइनरी में) है।
  2. यदि यह दोहराता है, तो किस अंक (2 की शक्ति के रूप में प्रतिनिधित्व किया जाता है) पुनरावृत्ति शुरू होता है?
  3. कौन से अंक दोहराते हैं?

कुछ उदाहरण:

1/2 = 1/10 = 0.1 // 1 = false, 2 = N/A, 3 = N/A, 4 = N/A 
1/3 = 1/11 = 0.010101... // 1 = true, 2 = -2, 3 = 10 
2/3 = 10/11 = 0.101010... // 1 = true, 2 = -1, 3 = 10 
4/3 = 100/11 = 1.010101... // 1 = true, 2 = 0, 3 = 10 
1/5 = 1/101 = 0.001100110011... // 1 = true, 2 = -3, 3 = 1100 

वहाँ यह करने के लिए कोई तरीका है? क्षमता एक बड़ी चिंता है। कोड पर एल्गोरिदम का विवरण पसंद किया जाएगा, लेकिन मैं जो जवाब प्राप्त कर सकता हूं उसे ले जाऊंगा।

यह भी ध्यान देने योग्य है कि आधार एक बड़ा सौदा नहीं है; मैं एल्गोरिदम को बाइनरी में बदल सकता हूं (या यदि यह है, तो आसानी से char एस का उपयोग करने के लिए आधार 256 कहें, मैं बस इसका उपयोग कर सकता हूं)। मैं यह इसलिए कहता हूं क्योंकि यदि आप समझा रहे हैं तो आधार 10 में व्याख्या करना आपके लिए आसान हो सकता है :)।

+0

परिणाम प्राप्त करने के लिए आपने और अधिक स्थितियों का उपयोग किया है? "01", "01", "10" और "0011" दोहराए गए अंक क्यों नहीं हैं? – Guffa

+0

@ गुफा मेरा तर्क 1 सबसे पहले रखना था क्योंकि प्रमुख शून्य [महत्वपूर्ण] [1] नहीं हैं, जबकि शून्य शून्य हैं। यदि संख्या कुछ थी, "111.010101 ...", दोहराव संख्या "01" होगी क्योंकि उस मामले में पहला 0 * महत्वपूर्ण * महत्वपूर्ण है। [1]: http: //en.wikipedia.org/wiki/Significant_digits – Imagist

+0

@ गुफा (जारी) हालांकि यह मेरे लिए महत्वपूर्ण नहीं है। अगर आपने मुझे बताया कि "01", "01", "01" और "0011" लौटने के तरीके से ऐसा कैसे किया जाए तो मैं खुश रहूंगा। :) – Imagist

उत्तर

1

दोहराई जाने वाली पद्धति को खोजने के लिए, बस मूल्यों आप रेखा के साथ उपयोग करने का ट्रैक रखने:

1/5 = 1/101: 

1 < 101 => 0 
(decimal separator here) 
10 < 101 => 0 
100 < 101 => 0 
1000 >= 101 => 1 

    1000 - 101 = 11 

110 >= 101 => 1 

    110 - 101 = 1 

10 -> match 

आप एक ही मूल्य तक पहुंचने के रूप में के रूप में आप दूसरे बिट में था, इस प्रक्रिया को सिर्फ इतना है कि से दोहराया जाएगा बिंदु पर एक ही बिट पैटर्न का उत्पादन बिंदु। आपके पास दूसरी बिट से दोहराने वाला पैटर्न "0011" है (दशमलव विभाजक के बाद पहले)।

आप पैटर्न एक "1" के साथ शुरू करना चाहते हैं, तो आप बस इसे बारी बारी से कर सकते हैं जब तक यह है कि हालत से मेल खाता है:

"0011" from the second bit 
"0110" from the third bit 
"1100" from the fourth bit 

संपादित करें: सी # में
उदाहरण:

void FindPattern(int n1, int n2) { 
    int digit = -1; 
    while (n1 >= n2) { 
     n2 <<= 1; 
     digit++; 
    } 
    Dictionary<int, int> states = new Dictionary<int, int>(); 
    bool found = false; 
    while (n1 > 0 || digit >= 0) { 
     if (digit == -1) Console.Write('.'); 
     n1 <<= 1; 
     if (states.ContainsKey(n1)) { 
     Console.WriteLine(digit >= 0 ? new String('0', digit + 1) : String.Empty); 
     Console.WriteLine("Repeat from digit {0} length {1}.", states[n1], states[n1] - digit); 
     found = true; 
     break; 
     } 
     states.Add(n1, digit); 
     if (n1 < n2) { 
     Console.Write('0'); 
     } else { 
     Console.Write('1'); 
     n1 -= n2; 
     } 
     digit--; 
    } 
    if (!found) { 
     Console.WriteLine(); 
     Console.WriteLine("No repeat."); 
    } 
} 

आपके उदाहरणों के साथ बुलाया गया यह आउटपुट:

.1 
No repeat. 
.01 
Repeat from digit -1 length 2. 
.10 
Repeat from digit -1 length 2. 
1.0 
Repeat from digit 0 length 2. 
.0011 
Repeat from digit -1 length 4. 
+0

मुझे यकीन नहीं है कि यह उसकी समस्या हल करता है क्योंकि कुछ अंश उदाहरण के लिए अंकों की एक निश्चित संख्या के बाद दोहराते हैं उदाहरण के लिए 5/6 = .8333333। तो आपके मॉडल के तहत यह पुनरावृत्ति खोजने के लिए 8 का उपयोग करेगा। – user20844

+0

@letseatunch: 5/6 = 101/110 = 0.11010101010101010 ... यदि आप FindPattern (5,6) चलाते हैं तो यह लंबाई 2 के साथ अंक -2 से दोहराए जाने वाले पैटर्न को मिलेगा। – Guffa

+0

मुझे समझने में थोड़ी देर लग गई कोड क्योंकि मुझे सी # बहुत अच्छी तरह से पता नहीं है, लेकिन मुझे लगता है कि यह वही है जो मैं देख रहा था। मैं इसे सी ++ में लिख रहा हूं और संख्या भंडारण बिल्कुल इस तरह से नहीं है, लेकिन इसे बंद करने के लिए यह आसान होना चाहिए। मदद के लिए आपका बहुत बहुत धन्यवाद! – Imagist

10
  1. यदि भाजक 2 के एक शक्ति नहीं है, लेकिन
  2. दोहराने चक्र लंबाई लाभांश में से सबसे बड़ी अभाज्य गुणांक के द्वारा संचालित किया जाएगा (सामान्य रूप में प्रधानमंत्री कारकों प्रतिनिधित्व के आधार के साथ साझा नहीं होता है) (नहीं उस कारक के प्रतिनिधित्व की लंबाई से जुड़ा हुआ - दशमलव में 1/7 देखें), लेकिन पहली चक्र लंबाई दोहराने वाली इकाई से भिन्न हो सकती है (उदाहरण के लिए दशमलव में 11/28 = 1/4 + 1/7)।
  3. वास्तविक चक्र संख्या पर निर्भर करेगा।
+0

+1 आपकी टिप्पणी के लिए धन्यवाद। यह मुझे समस्या में कुछ अंतर्दृष्टि देता है। विशेष रूप से विचार यह है कि चक्र की लंबाई और वास्तविक चक्र विभिन्न कारकों द्वारा संचालित होते हैं। मुझे पता था कि चक्र को संग्रहित करने के लिए महत्वपूर्ण होगा लेकिन मैंने यह नहीं सोचा कि चक्र की गणना के लिए यह महत्वपूर्ण हो सकता है। हालांकि, मैं अभी भी नहीं देखता कि जानकारी की गणना कैसे करें। – Imagist

3

decimal expansion, और विशेष रूप से एक अंश की अवधि के बारे में देखें।

+1

+1 आपकी पोस्ट के लिए धन्यवाद। इससे मुझे समस्या को समझने में मदद मिली। – Imagist

8

मैं आधार दस में एक संकेत - दोहराव decimals दे सकते हैं कम से कम एक और पांच के अलावा कम से कम एक प्रमुख कारक वाले denominator के साथ सभी अंश हैं। यदि denominator में दो या पांच कोई प्रमुख कारक नहीं है, तो वे हमेशा सभी नाइन के एक denominator के साथ प्रतिनिधित्व किया जा सकता है। फिर नामांकनकर्ता दोहराना हिस्सा है और नाइन की संख्या दोहराने वाले भाग की लंबाई है।

3  _ 
- = 0.3 
9 

1 142857  ______ 
- = ------ = 0.142857 
7 999999 

यदि denominator में दो या पांच प्रमुख कारक हैं, तो दोहराव वाला हिस्सा पहली स्थिति में शुरू नहीं होता है।

17 17  ______ 
-- = ----- = 0.4857142 
35 5 * 7 

लेकिन मुझे याद नहीं है कि गैर-दोहराने वाले भाग और इसकी लंबाई को कैसे प्राप्त किया जाए।

यह दो आधार पर अच्छी तरह से अनुवाद करने लगता है। दो denominator की शक्ति के साथ केवल अंश गैर-दोहराना है। यह आसानी से जांच कर किया जा सकता है कि denominator में केवल एक ही बिट सेट है।

1/2 = 1/10 = 0.1 
1/4 = 1/100 = 0.01 
3/4 = 11/100 = 0.11 
5/8 = 101/1000 = 0.101 

सभी अंश अजीब हरों साथ दोहरा किया जाना चाहिए और पैटर्न और इसकी लंबाई प्रपत्र 2^n-1 में एक विभाजक के साथ अंश व्यक्त करके प्राप्त की जा सकती है। उदाहरण 12 = 3 * 2^2 के लिए -

             __ 
1/3   = 1/(2^2-1) =  1/11  = 0.01 
                __ 
2/3   = 2/(2^2-1) =  10/11  = 0.10 
         __ 
4/3 => 1 + 1/3 => 1.01 
         __ 
10/3 => 3 + 1/3 => 11.01 
                ____ 
1/5 = 3/15 = 3/(2^4-1) =  11/1111  = 0.0011 
                ________ 
11/17 = 165/255 = 11/(2^8-1) = 10100101/11111111 = 0.10100101 

आधार दस का सवाल है, मैं कैसे युक्त हरों लेकिन दोनों में से एक शक्ति नहीं किया जा रहा संभालने के लिए नहीं बता सकता।

+0

+1 इस तर्क से, बेस 2 में, दशमलव को दोहराना दोहरे के अलावा प्रमुख कारक वाले denominators के साथ भिन्नता है (मुझे यह पता था)। मुझे नहीं पता था कि अगर उनके पास एक प्रमुख कारक था तो यह पहली स्थिति के अलावा कहीं और शुरू हुआ (यह उपयोगी जानकारी है!)। आपके तकनीकी इनपुट के लिए – Imagist

5

सबसे पहले, आपके उदाहरणों में से एक गलत है। 1/5 का दोहराव हिस्सा 00111100 के बजाय है, और यह आंशिक भाग की शुरुआत में ही शुरू होता है। जिसमें

a/b = c + d(2-n + 2-n-k + 2-n-2k + ...)
    = c + 2-n * d/(1 - 2-k)

n और d आप क्या चाहते हैं:

एक दोहराई जाने वाली दशमलव की तरह कुछ है।

उदाहरण के लिए

,

1/10(dec) = 1/1010(bin) = 0.0001100110011... // 1 = true, 2 = -1, 3 = 0011

a = 1, b = 10(dec), c = 0, d = 0.0011(bin), n = 1, k = 4;
(1 - 2-k) = 0.1111

इसलिए, 1/10 = 0.1 * 0.0011/0.1111 साथ सूत्र द्वारा प्रतिनिधित्व किया जा सकता है। दोहराने वाले दशमलव प्रतिनिधित्व का मुख्य भाग (2n - 1) या उसके किसी भी एकाधिक 2 से विभाजित करके उत्पन्न होता है। तो आप या तो अपने denominator को व्यक्त करने के लिए एक रास्ता खोज सकते हैं (जैसे निरंतर तालिकाओं का निर्माण), या एक बड़ी संख्या विभाजन (जो है अपेक्षाकृत धीमी) और लूप पाएं। ऐसा करने का कोई त्वरित तरीका नहीं है।

+0

+1। हालांकि गुफा की विधि बहुत प्रभावी प्रतीत होती है और ऐसा लगता है कि यह संख्या की लंबाई के संबंध में रैखिक होगा, जो कि पर्याप्त तेज़ है क्योंकि यह संभवतः अक्सर छोटी संख्याओं के साथ उपयोग किया जाएगा। हालांकि यह मुझे मनमाना-परिशुद्धता फ्लोटिंग पॉइंट ऑपरेशंस का समर्थन करने की अनुमति देता है, वास्तविक उद्देश्य आधार 10 संख्याओं को सटीक रखना है (यानी अधिकांश भाषाओं में 1.1 बेस 10 1.100000001 या कुछ दशकों को दोहराने के कारण आता है)। – Imagist

+0

असल में आपके उद्देश्य को बेहतर तरीके से दिए गए हैं: आप तर्कसंगत संख्याओं को विस्तारित करने के बजाय अंश रूप में रख सकते हैं, या आप बस आधार 10 में गणित कर सकते हैं। प्रोसेसिंग decimals प्रसंस्करण काफी आसान नहीं है जैसा कि मैं कल्पना करता हूं। :) –

0

आप ca n long division, रहने वालों को ध्यान में रखते हुए करें। शेष की संरचना आप किसी भी तर्कसंगत दशमलव की संरचना दे देंगे:

  1. पिछले शेष शून्य है: यह किसी भी दोहरा हिस्सा
  2. पहली और आखिरी शेष बराबर हैं के बिना एक दशमलव है: दशमलव सही डॉट के बाद दोहरा रहा है
  3. पहले और पहले शेष पिछले करने के लिए बराबर के बीच की दूरी गैर अंक समान हैं, शेष दोहरा हिस्सा

सामान्य दूरी वाई में है आपको प्रत्येक भाग के लिए अंकों की राशि देगी।

आप इस एल्गोरिथ्म विधि decompose()here में सी ++ में कोडित देख सकते हैं।

Try228142/62265, यह अंक की अवधि है!

संबंधित मुद्दे