2011-12-16 24 views
7

मैं रूबी में 0.0001 चरणों के साथ 0.0001 से 1 तक गिनना चाहता हूं। मैंने यह कोड लिखा लेकिन यह एक अनंत लूप में प्रवेश करता है। Somewhy दुभाषिया गलत सारांश करता है।रूबी में 0.0001 से 1 तक कैसे गिनें?

x = 0.0001 
while x != 1.0 
    puts x 
    x = x + 0.0001 
end 

यहाँ है पहले 10 मूल्य यह देता है:

0.0001 
0.0002 
0.00030000000000000003 
0.0004 
0.0005 
0.0006000000000000001 
0.0007000000000000001 
0.0008000000000000001 
0.0009000000000000002 
0.0010000000000000002 

यह होना चाहिए 0.0001, 0.0002, 0.0003, आदि ... मैं कैसे यह काम कर रहा कर सकते हैं? धन्यवाद!

+0

दिलचस्प है, यह JRuby पर नहीं होता है। –

+0

gioele का उत्तर स्पष्ट रूप से चिह्नित एक से बेहतर है। – steenslag

उत्तर

2

समस्या यह है कि रूबी में असली संख्या बाइनरी स्टोरेज और हेरफेर के कारण बिल्कुल प्रदर्शित नहीं होती है। मैं यह

x = 1 
while x < 10000 
    puts (x/10000).round(4) 
    x += 1 
end 
+0

धन्यवाद! :) मैंने अभी प्रोग्रामिंग शुरू की है। मुझे यह नहीं पता था! :) – Hiddin

+4

बस स्पष्ट करने के लिए, यह रूबी तक ही सीमित नहीं है, यह एक फ़्लोटिंग पॉइंट मुद्दा है। –

1

x != 1.0 की बजाय, x < 1.0 डालें। यह कम से कम सुनिश्चित होगा कि आपका लूप समाप्त हो जाएगा।

हमारे सभी आधुनिक कंप्यूटर चलाने वाले लोगों की तरह एक द्विआधारी प्रणाली (आसानी से) भिन्नता का प्रतिनिधित्व नहीं कर सकती है, खासतौर पर उन लोगों को जिन्हें दशमलव में सटीक रूप से प्रदर्शित नहीं किया जा सकता है। यही वह जगह है जहां अजीब संख्या आती है जब आपके पास .0003 होना चाहिए। यह एक आर्टिफैक्ट है कि संख्याओं को आंतरिक रूप से कैसे दर्शाया जाता है।

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

+0

हां यह काम कर रहा है। लेकिन अगर मुझे सटीक परिणाम चाहिए तो क्या करना है? और क्यों 0.0005 + 0.0001 0.0006000000000000001 ruby ​​के बराबर है? – Hiddin

+0

मेरा अद्यतन उत्तर देखें। – cdeszaq

+2

फ़्लोटिंग नंबर काम करने के तरीके के कारण: http://floating-point-gui.de/ – gioele

16

इस प्रयास करें:

0.0001.step(1, 0.0001).each { |i| puts i } 

संपादित: क्योंकि यह आपको नाव गणित के weirdness से ढाल आप Float#step विधि का उपयोग करना चाहिए। Float#step मूल्य को बढ़ाने और फ़्लोट-सबूत तरीके से सीमा की तुलना करने का ख्याल रखेगा। अधिक जानकारी के लिए the official documentation of Float#step पर एक नज़र डालें।

+1

एक और बेवकूफ संस्करण – cdeszaq

+0

के लिए +1 धन्यवाद! यह नौकरी बनाता है :) – Hiddin

0

फ़्लोटिंग पॉइंट नंबर सटीक सटीक नहीं हैं Wikipedia Floating Point article

यदि आपके पास स्वच्छ एक्स होना चाहिए, तो मैं मूल्य का उपयोग करने से पहले एक पूर्णांक का उपयोग करने और 1000 तक विभाजित करने की अनुशंसा करता हूं। यदि आपको शोर के छोटे बिट्स की परवाह नहीं है, तो आप अपने समय x = = 1.0 को बदलकर ठीक होंगे, जबकि x < 1.0

+0

मैं सहमत हूं। आम तौर पर, संचालन के लिए पूर्णांक का उपयोग (यदि संभव हो) और फिर अंत में परिवर्तित करने से अधिक सटीक परिणाम मिलेंगे। – cdeszaq

+0

फ्लोटिंग पॉइंट नंबरों (जैसे आईईईई 754) के सामान्य बाइनरी _representations_ सटीक नहीं हैं। –

+0

माइकल, क्या आप कह रहे हैं कि गणित विश्वसनीय है लेकिन आउटपुट समस्या है? –

0

जो आप देख रहे हैं वह फ़्लोटिंग-पॉइंट नंबरों के द्विआधारी प्रतिनिधित्व के कारण है । यह सभी कंप्यूटर प्रोग्रामिंग भाषाओं को प्रभावित करता है। अधिक जानकारी के लिए What Every Computer Scientist Should Know about Floating Point Arithmetic देखें।

आप क्या कर सकते हैं प्रिंट समय में अंक की उचित संख्या के लिए यह दौर है, या के रूप goiele पाया गया है, step का उपयोग करें:

0.0001.step(1, 0.0001).each do |i| 
    puts i 
end 
+0

धन्यवाद! मैं इसे पढ़ूंगा! और कोड भी ठीक काम कर रहा है :) – Hiddin

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

  • कोई संबंधित समस्या नहीं^_^