2014-09-01 4 views
5

मुझे एहसास है कि यह एक हानिकारक बग है लेकिन मैं अभी भी समझना चाहता हूं कि क्या हो रहा है।क्रोम (.1) .toString (3) के लिए डॉट के बाद 1099 अंकों का उत्पादन क्यों करता है?

मैं कैनवास पर Peano curve प्रस्तुत करने के लिए कुछ कोड के साथ खेल रहा था जिसमें बेस 3 में तार्किक निर्देशांक व्यक्त करना शामिल था जब मैंने देखा कि एक फ़ंक्शन क्रोम में बेहद लंबे तारों को वापस कर रहा था। और अधिक बारीकी से देख रहे हैं, यह पता चला है कि अभिव्यक्ति

(.1).toString(3) 

0,002200220022002200220022002200220100002100210000110101000202201120201212110212202011212000102021022210120112001022101010120202020022102010100200210110010000202221001022002202102122102110002012010220202020011000222022001200102102202000112022010100102211212012122021012212120012120012221210011021010220200001202121120022222110111121112201212111120221121001002221210000221022021012220020112022001121012011001112000001101100101011002201210200110202021021120211100100210120010202222111221201201100002211002202000110011221210 लिए क्रोम में मूल्यांकन करता है 2102100111000222211012211220200112120002100121210000222002201120220111022021120022101112201220001101012112201211010010110122011201120022210102021100002000121020120001112122222220201200220012211122001022022001222011221100212001100010200001211022021120210222110022221202002120011210220012001022112012202110101212100011220000220200122222102201100202101012110201221202211220201111021112112201120101121122212112220211110002020120201022022121210120002202021212000101222221101122201001100021211101012101011202020110010112202201201001020212002021112020021121202000000222122210022012001201

यहाँ देखा के रूप में: http://jsfiddle.net/zvp8osm8/

मैं क्या बता सकते हैं के लिए, केवल पहले 33 डॉट के बाद अंक में मतलब इस मामले में, शेष पहचानने योग्य पैटर्न के बिना यादृच्छिक कचरा जैसा दिखता है। विभिन्न बेस और एक्सपोनेंट्स के लिए (10000000000.1).toString(3) या (.7).toString(7) जैसे डॉट के बाद 1099 (!) अंक के साथ इसी तरह के परिणाम उत्पन्न होते हैं। (.5).toString(3) जैसे अन्य मान भी तारों का उत्पादन करते हैं, लेकिन सभी अंक समझ में आते हैं।

ओपेरा के अपवाद के साथ अन्य ब्राउज़र केवल हर मामले में अंकों की उचित संख्या उत्पन्न करते हैं, जो मुझे लगता है कि समस्या क्रोम के जावास्क्रिप्ट इंजन में है।

मैं अब दो प्रश्न हैं:

  • क्यों आधार 3 में दशमलव संख्या का प्रतिनिधित्व क्रोम में इतने सारे तुच्छ अंक होने करता है?
  • यादृच्छिक अंक संभवतः कहां से आ सकते हैं?
+0

आधार 5, 7, 9, आदि भी एक ही परिणाम उत्पन्न करते हैं। शायद इसके पीछे तर्क अजीब आधार मूल्य है। – VisioN

+0

कोई आपको बेहतर तरीके से भर देगा, लेकिन मैं अनुमान लगा रहा हूं कि ऐसा इसलिए है क्योंकि बाइनरी में 0.1 का प्रतिनिधित्व करने का कोई सटीक तरीका नहीं है। (फ़्लोटिंग पॉइंट त्रुटियों को देखें) – Mardoxx

उत्तर

5

आपके द्वारा दिखाए जाने वाले विशेष मामले के लिए, ऐसा लगता है कि x = .1 से शुरू होने वाले निम्न बेवकूफ एल्गोरिदम का उपयोग करके अंक उत्पन्न किए जा रहे हैं।

  1. गुणा x द्वारा 3.
  2. पूर्णांक और परिणाम की आंशिक भागों निकालें।
  3. एक अंक के रूप में पूर्णांक भाग आउटपुट, और x को आंशिक भाग के साथ प्रतिस्थापित करें।
  4. ऊब तक चरण 1 से 3 दोहराएं (या कुछ प्रीसेट सीमा प्राप्त होने तक)।

यह गणितीय ठीक काम करेगा, लेकिन फ्लोटिंग प्वाइंट की दुनिया में यह बोलना बकवास, निश्चित रूप से गुणा के बाद से 3 से है, और निकटतम फ्लोटिंग प्वाइंट नंबर के लिए बाद में दौर संभवतः एक छोटे से त्रुटि का परिचय है, और 30 अंकों के बाद या तो त्रुटि ने मूल अंक को पूरी तरह से घुमा दिया है, और हम सिर्फ कचरा प्राप्त कर रहे हैं।

संभावित रूप से उस मामले के बिंदु से पहले अंकों को संभालने का कुछ तरीका भी है जहां प्रारंभिक संख्या 1.0 से अधिक मूल्य में बड़ी है, लेकिन नमूना आउटपुट के बिना, मुझे यह अनुमान लगाने वाला नहीं है कि वह एल्गोरिदम क्या है।

उपरोक्त को न्यायसंगत बनाने के लिए, यहां पाइथन में कुछ कोड है जिसका आउटपुट प्रश्न में दिए गए बिल्कुल मेल खाता है। यहां, modf वह ऑपरेशन है जो पाइथन फ्लोट के आंशिक और अभिन्न अंगों को निकालता है।

>>> from math import modf 
>>> x = 0.1 
>>> digits = [] 
>>> for _ in xrange(1099): 
...  x, digit = modf(3.0 * x) 
...  digits.append(str(int(digit))) 
... 
>>> print('0.' + ''.join(digits)) 

और उत्पादन:

0,00220022002200220022002200220022010000210021000011010100020220112020121211021220201121200010202102221012011200102210101012020202002210201010020021011001000020222100102200220210212210211000201201022020202001100022202200120010210220200011202201010010221121201212202101221212001212001222121001102101022020000120212112002222211011112111220121211112022112100100222121000022102202101222002011202200112101201100111200000110110010101100220121020011020202102112021110010021012001020222211122120120110000221100220200011001122121021021001110002222110122112202001121200021001212100002220022011202201110 22021120022101112201220001101012112201211010010110122011201120022210102021100002000121020120001112122222220201200220012211122001022022001222011221100212001100010200001211022021120210222110022221202002120011210220012001022112012202110101212100011220000220200122222102201100202101012110201221202211220201111021112112201120101121122212112220211110002020120201022022121210120002202021212000101222221101122201001100021211101012101011202020110010112202201201001020212002021112020021121202000000222122210022012001201

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

+0

प्रत्येक फ्लोटिंग-पॉइंट नंबर जो 1/एन से अधिक है, 53+ में सटीक रूप से प्रदर्शित होता है एलजी (एन) या किसी भी संख्या वाले आधार में कम अंक, लेकिन गैर-शून्य अंश भाग वाले कोई फ़्लोटिंग-पॉइंट नंबर किसी भी विषम-संख्या वाले आधार में अंकों की किसी भी संख्या में सटीक रूप से प्रदर्शित नहीं होता है। मुझे लगता है कि क्रोम तब तक पुनरावृत्त हो जाता है जब तक अवशेष शून्य न हो (जो कि संख्याबद्ध आधारों के साथ भी होगा, और अजीब संख्या वाले अड्डों के साथ नहीं होगा) या जब तक यह "ऊब" न हो जाए [लूप पर "सुरक्षा" सीमा को मारना] । – supercat

2

पहले नंबर .1 को फ्लोटिंग पॉइंट में परिवर्तित किया जाना है, जो बाइनरी में दर्शाया गया है। बाइनरी में, .1 को सटीक रूप से प्रदर्शित नहीं किया जा सकता है, इसलिए निम्न-आदेश अंकों में कुछ त्रुटि कहां होगी। यह दशमलव में 1/7 का प्रतिनिधित्व करने की कोशिश करने के समान है: यह दोहराना अनुक्रम .142857 142857 ... है; जहां भी आप इसे समाप्त करेंगे, आपको सटीकता का नुकसान होगा।

जब इसे फिर बेस 3 में परिवर्तित किया जाता है, तो उन अंकों में त्रुटि के परिणामस्वरूप यादृच्छिकता दिखाई देती है।

+0

हालांकि बेस 2 या 4 उसी फ्लोट वैल्यू के लिए "सीमित" संख्याओं की संख्या प्रदर्शित करेगा। ऐसा लगता है कि किसी भी तरह से आधार से संबंधित है। – VisioN

+0

आंतरिक प्रतिनिधित्व आधार 2 है। इसलिए यह बिट्स को आंतरिक प्रतिनिधित्व से कॉपी करता है, जिसमें बिट्स की सीमित संख्या होती है। – Barmar

+2

@VisioN Radix 2 और 4 दोनों में संपत्ति है कि किसी भी समाप्ति अंश को आधार 10 अंश को समाप्त करके भी प्रदर्शित किया जा सकता है। ऐसा इसलिए है क्योंकि एकमात्र प्रमुख कारक, 2, 10 का कारक भी है, दूसरी ओर, 10 का कारक नहीं है। –

1

ईसीएमएस्क्रिप्ट 5 के साथ शुरू करना।1 कल्पना, अर्थात् 15.7.4.2 Number.prototype.toString([radix]) और 9.8.1 ToString Applied to the Number Type:

एक स्ट्रिंग के लिए एक नंबर परिवर्तित करने के लिए सटीक एल्गोरिथ्म कार्यान्वयन पर निर्भर करता है, तो मूलांक नहीं 10 (15.7.4.2 देखें), तथापि, यह एल्गोरिथ्म का सामान्यीकरण होने की उम्मीद है है 9.8.1 में उल्लिखित।
इसका मतलब है कि प्रत्येक ब्राउज़र (और हर दूसरे कार्यान्वयन) यह चुनने के लिए स्वतंत्र है कि वे मानक परिशुद्धता (21 अंकों तक) या अधिक देना चाहते हैं या नहीं।

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